微信小程序
https://github.com/artiely/taro3-test
小程序基础库: 2.9.1
使用框架: React
重现链接是仓库地址。
长列表无明显卡顿。之前是taro1.0写的,无卡顿
demo中一个虚拟列表和一个普通的列表,列表中的子组件有100个空节点,虚拟列表滚动时会有明显的渲染跟不上滚动的情况导致页面卡顿和空白,节点越多越明显。
普通列表滚动到底分页时会有明显的卡顿,直到下一页渲染完成才能滚动,taro1.0是无缝衔接的。
虽然实际项目子节点可能没这么多,但是有更为复杂的逻辑和嵌套关系,效果比demo的更为明显。
👽 Taro v3.0.18
Taro CLI 3.0.18 environment info:
System:
OS: macOS 10.15.7
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 12.19.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 6.14.8 - /usr/local/bin/npm
npmPackages:
@tarojs/components: 3.0.18 => 3.0.18
@tarojs/mini-runner: 3.0.18 => 3.0.18
@tarojs/react: 3.0.18 => 3.0.18
@tarojs/runtime: 3.0.18 => 3.0.18
@tarojs/taro: 3.0.18 => 3.0.18
@tarojs/webpack-runner: 3.0.18 => 3.0.18
babel-preset-taro: 3.0.18 => 3.0.18
eslint-config-taro: 3.0.18 => 3.0.18
react: ^16.10.0 => 16.14.0
公司最近决定将项目升级到3.0,希望能带来开发体验的提升和性能的提升,在对代码进行升级后,发现页面的渲染都变得极其的慢,页面数据回来后得2-3s才能渲染出界面,列表分页尤为明显。
我从3.0.14 升级到3.0.18 似乎有点点改善,但是还是无法达到预期。
@aijiacy taro 1 - taro 2 都是编译型的和你直接写原生没有太大区别,taro 3 是运行时的,也就是说 Taro 的 setState 并不是小程序的 setState。当你的数据经过 Taro.setState ,Taro 首先对你的数据进行了一次 diff 然后才交给 wx.setState。(这是我在 #8267 回答的一部分,应用于这里也是一样的)。Taro diff 完之后就直接把 Data 塞到 wx.data 里了,也就是说,对于 wx 来说这次的 setState 是全量。全量的 setState 在小程序里意味着啥。。。
在 Taro 3 里,或者说在所有的运行时框架里(remax)长列表这类 setState 量大或者频繁进行的都不会有原生的表现好。白屏是正常的。
你可以混合原生的写法,当前这个页面使用原生来实现。
虚拟列表更多应该使用在超长列表的无限滚动下,这样的场景才可以体现其性能提升的优越性,以下几种情况不应该使用虚拟列表来完成性能优化:
长列表有很多情况,除了虚拟列表,分页加载也是一个很好的优化方案,虚拟列表本身不应该被滥用
demo中一个虚拟列表和一个普通的列表,列表中的子组件有100个空节点,虚拟列表滚动时会有明显的渲染跟不上滚动的情况导致页面卡顿和空白,节点越多越明显。
普通列表滚动到底分页时会有明显的卡顿,直到下一页渲染完成才能滚动,taro1.0是无缝衔接的。
虽然实际项目子节点可能没这么多,但是有更为复杂的逻辑和嵌套关系,效果比demo的更为明显。
该类情况中,如考量过需要使用虚拟列表,应该考虑提高 overscanCount 来优化显示效率,避免快速滚动情况下加载不及时的问题
该类情况中,如考量过需要使用虚拟列表,应该考虑提高 overscanCount 来优化显示效率,避免快速滚动情况下加载不及时的问题
事实上,在微信小程序里提高 overscanCount 带来的效率并没有 Taro 2 明显,期待新版的 VirtualList 可以在多端有更好的表现
事实上,在微信小程序里提高 overscanCount 带来的效率并没有 Taro 2 明显,期待新版的 VirtualList 可以在多端有更好的表现
这是当然的,不论是编译时还是运行时的差异,还是列表和虚拟列表应对的场景有明显不同,并不能一概而论。虽然这些问题都会随着框架的演进不断缩小差距。
在四五年前的手机比如 iPhone 6s 上,用虚拟列表渲染一个商品列表性能还是太难以接受了,overscanCount 增加到 2、3 的样子反应会更卡顿,基本上只能缓慢的滑动的时候不会白屏,稍微尝试手快一些就开始白一片。
"@tarojs/taro": "3.0.26"
在四五年前的手机比如 iPhone 6s 上,用虚拟列表渲染一个商品列表性能还是太难以接受了,overscanCount 增加到 2、3 的样子反应会更卡顿,基本上只能缓慢的滑动的时候不会白屏,稍微尝试手快一些就开始白一片。
"@tarojs/taro": "3.0.26"
可以通过加大 itemCount 来优化这个问题
@ZakaryCode 谢谢,我增加了 itemCount,页面变长了,但没有看到白屏问题的改善。
我觉得就是目前的 3.x 版本 Taro 的实现方式每次全量更新整个虚拟列表可视范围所有的组件,对于超过 3 年历史的手机来说,setData 性能跟不上。
其它组件我觉得都没啥大问题,主要其它组件也不存在一次性大面积更新视图的情况。或多或少都可以优化不要一次性更新那么大范围的视图。虚拟列表虽然不用几页的视图同时更新,但对更新的频率要求高了很多。
@ZakaryCode 谢谢,我增加了
itemCount,页面变长了,但没有看到白屏问题的改善。我觉得就是目前的 3.x 版本 Taro 的实现方式每次全量更新整个虚拟列表可视范围所有的组件,对于超过 3 年历史的手机来说,setData 性能跟不上。
其它组件我觉得都没啥大问题,主要其它组件也不存在一次性大面积更新视图的情况。或多或少都可以优化不要一次性更新那么大范围的视图。虚拟列表虽然不用几页的视图同时更新,但对更新的频率要求高了很多。
改用 position: 'relative' 会降低视图属性修改的频率,还是需要根据具体的业务来进行考量