React Native在0.43版本之前写列表需要使用ListView,ListView存在性能问题,API也不友好,所以官方在0.43版本推出了FlatList,有如下优点:
- API更加友好和丰富;
- 性能好很多;
所以我写了一个长列表Demo来测试下两者性能对比(测试环境是MacBook Air的iphone8plus模拟器,关闭了remotedebug)。
ListView without removeClippedSubviews vs FlatList:
- 内存:ListView在上下滚动的时候内存从200M 涨到了1个G 还不止(我觉得ListView最大的性能问题是上下滚动的时候内存不会被回收,会无限增大),但是FlatList无论你怎么滚动,都可以稳定在320M!
- CPU:ListView在上下滚动的时候CPU峰值达到160%,但是FlatList稳定在50%左右。
ListView with removeClippedSubviews(ListView开启设置定高并且overflow:hidden即可) vs FlatList:
- 内存:ListView的峰值是135.8M,FlatList是265M。之所以FlatList高是因为windowSize默认为21,渲染了一些可视区之外的元素所以内存占用较高,当我把windowSize设置为10的时候内存占用降低到了160M。
- CPU:ListView在上下快速滚动的时候峰值达到200%,但是FlatList峰值最高是80%。(其实CPU峰值和滑动列表速度有关,但是基本上可以看到无论哪种情况ListView的CPU峰值是FlatList的2~3倍左右)
如果要写出高性能的FlatList需要注意:
- renderItem中的组件最好是无状态组件,不要放内存state。
- 使用keyExtractor指定一个key,不要使用索引,尤其是存在列表的增删的情况下。
- 如果你不需要渲染就知道每一行的高度的话,那么getItemLauout是一个非常有用的优化方案。
- 使用合适的windowSize在内存和流畅性之间达到平衡。
PS:本文首发在简书。