主流列表组件分析
-
FlstList
由RN官方提供用于取代ListView,核心是以释放内存来达到优化目的。- 性能方面
如何使用得当,例如配合removeClippedSubviews、windowSize属性(removeClippedSubviews用于控制白屏逻辑、windowSize用于控制子组件的销毁)可以将内存消耗控制在一定范围之内,再加上对长列表中的网络图片的缓存控制,是可以达到一定的性能优化目的,但是对于对用户体验要求比较高的项目不建议使用,有两点是不能忍受的。
- removeClippedSubviews属性默认在Android端为true,IOS端为false,如果对性能有极致要求,我们必然是将两端统一置为true,但是IOS设备在一级列表界面的切换等操作会出现白屏问题(同级界面切换中出现),这是不能忍受的。
- 数据量达到数百条乃至更多的数据,出现的界面闪屏、抖动问题,这个在双端都有复现,只是概率大小问题。
- 瀑布流
对于瀑布流的支持FlatList组件本身做的不多,只是提供了numColumns属性,但是稍加改造是可以实现的,当然如果你的项目有非等高多列瀑布流的场景你可能需要做两件事情- 对ListItem的布局进行精确计算,核心是两个参数,height、marginTop。
- 很有可能会遇到瀑布流底部加载顺序异常问题,这时候你需要改造removeClippedSubviews属性的原生逻辑,听着有点唬人,其实不复杂,几行代码的事情。我这里有比较成熟的方案,可以在评论区留言,互相探讨学习。
总而言之,对于无限长列表,果断弃用,对于有限短列表,我还是会采用FlatList,不能一棒子打死。
- 性能方面
-
LargeList
这个组件使用的人也很多,组件文档也比较全,如果你的RN版本较低(如果没记错的0.60以下),短时间又没有升级打算,可以使用这个组件,之前的项目大规模用过,从稳定性上来说比FlatList强,只是目前停更了,估计是优化方案上遇到了瓶颈,其他的不予置评。 -
RecyclerListView,今天的主角
公司的一位好大哥在Github上发现的这个组件,这么牛的组件搞了这么久RN我还不知道,看名字让人想起了原生的RecyclerView,第一印象很厉害。今天我们先简单分享以下我认为比较厉害的几个方面,关于项目实战和遇到的问题,其他文章会进行详解。- 稳定性
600+复杂的图文混编dom没有界面抖动和闪屏,稳定性很可靠。 - 绝对布局
绝对布局的好处在于针对多列瀑布流的需求在这个组件上可以很方便的的进行魔改,核心思路是改造LayoutManager,比改造FlatList要简单的多。 - 内存复用
这个词貌似在原生中提的多一些,对于纯JS库的组件是如何体现的?
核心就是旧dom的key进行复用,当然组件本身通过监听界面滑动有一套严格的算法来维护recyclePool,来保证children的key是唯一的,为什么复用key就可以实现内存复用,关于这个问题大家可以去了解以下key对于dom diff算法的影响。// 内存复用的痕迹,取自方法VirtualRenderer.prototype.syncAndGetKey key = this._recyclePool.getRecycledObject(type);
- children的key是唯一的前提条件
即使我们提供的dataProvider的size是一个极大值,但是实际上整个列表只展示可视区域的dom,精确范围为窗口高度+renderAheadOffset,这样非展示区域的dom所属的key就可以被复用了。
如何幸运的话recyclerlistview的基础用法已经可以满足你的需求,而且内存情况会非常理想,一般情况下内存只会在窗口高度+renderAheadOffset增长,因为这时候缓存池是空的,之后内存会稳定在一个范围内进行波动。
如果你的业务情况比较特殊,发现内存情况不是很理想,和FlatList差异不大,甚至更差劲,那就需要对type这个概念进行深入理解。下篇文章会讲到。 - 稳定性