大型列表的React-Native FlatList性能问题

buc*_*csy 9 javascript react-native react-native-android react-native-flatlist

我的代码获取Json数据到一个数组使用a列出数据FlatList.它看起来像电话簿照片和文本连续.

这是我的代码:

  renderItem = ({ item }) => 
    (
    <ListItem
      title={item.username}
      avatar={{ uri: item.photo }}
    />
    )


  render() {
    console.log(this.state.myData);
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.myData}
          renderItem={this.renderItem}
        />
      </View>
    );
  }
Run Code Online (Sandbox Code Playgroud)

它的工作和我得到输出,但性能很慢.渲染大约需要10秒钟,这对用户来说很烦人.我该怎么做才能让它更快?

Fil*_*ker 23

这个答案在github上成为一个更大更完整的帖子


如果你遵循这个主题,你会发现react的团队已经意识到了这个性能问题.

对于这个问题没有灵丹妙药,你必须考虑每种方法的权衡以及你认为对你的观众来说是一种很好的体验.但幸运的是,你可以尝试一些调整来改善你的想法FlatList.


术语和含义

有很多术语(在文档或某些问题上)一开始让我感到困惑.所以,让我们从一开始就解决这个问题.

  • VirtualizedList是背后的组件FlatList,是React Native对" 虚拟列表 "概念的实现.

  • 在这种情况下,性能意味着平滑(不波涛汹涌)的滚动(以及导入或导出列表)体验.

  • 在这种情况下,内存消耗是指您的列表中有多少信息存储在内存中,这可能会导致应用程序崩溃.
  • 空白区域表示VirtualizedList无法足够快地渲染您的项目,因此您使用非渲染组件输入列表的一部分.
  • 这里的窗口不是您的视口,而是应该呈现项目的区域的大小.

道具

改善你的一种方法FlatList是调整它的道具.以下列出了可以帮助您实现这一目标的道具.

removeClippedSubviews

您可以将removeClippedSubviewsprop 设置为true,从而卸载窗口外的组件.

Win:这是非常友好的,因为你总会有一个小的渲染列表.

权衡:请注意,此实现可能存在错误,例如,如果您在无法卸载的组件(例如导航路径)上使用它,则会丢失内容.它也可能性能较差,在不太好的设备上使用复杂项目的大型列表具有不连续的滚动动画,因为它会对每个滚动进行疯狂的计算量.

maxToRenderPerBatch

你可以设置maxToRenderPerBatch={number},这是一个VirtualizedList可以直接传递给它的道具FlatList.通过这种方式,您可以控制每批渲染的项目数量,这是每个卷轴上呈现的下一个项目块.

赢:设置更大的数字意味着滚动时可视空白区域更少(填充率更好).

权衡:每批更多项目意味着更少的JavaScript性能,这意味着更少的响应能力(单击项目并打开详细信息).如果您有一个静态和非交互式列表,这可能是要走的路.

initialNumToRender

你可以设置initialNumToRender={number}.这意味着要渲染的项目的初始数量.

赢:您可以将此值设置为覆盖每个设备屏幕的精确项目数.渲染列表组件时,这可以大大提升性能.

权衡:设置低价时,您最有可能看到空白区域initialNumToRender.

windowSize

你可以设置windowSize={number}.此处传递的数字是一个测量单位,其中1等于您的视口高度.默认值为21,上面是10个视口,下面是10个视图,中间是一个.

赢:如果您主要担心性能问题,可以设置更大,windowSize以便您的列表运行顺畅,空格更少.如果您主要担心内存消耗,可以设置较低的值,windowSize以便渲染列表更小.

权衡:对于更大的windowSize,你会有更大的内存消耗.对于较低的windowSize,您将看到空白区域的性能较低和更大的变化.

legacyImplementation

这个道具,如果属实,会让你FlatList依赖于年长的ListView,而不是VirtualizedList.

赢:这将使您的列表绝对更好,因为它删除虚拟化并立即呈现所有项目.

权衡:你的内存消耗量上升到很高的可能性,包含复杂项目的大型列表(100+)会使你的应用程序崩溃.它还会发出上述调整不起作用的警告,因为您现在使用的是ListView.

disableVirtualization

你会看到人们在某些问题上建议使用这个道具.但现在已经弃用了.这曾经做过类似的事情legacyImplementation.


列出项目

还有一些涉及您的列表项组件的双赢策略.它们很多都是由VirtualizedList管理的,所以它们需要很快.

使用简单的组件

组件越复杂,渲染速度就越慢.尽量避免在列表项中使用大量逻辑和嵌套.如果您在应用程序中重复使用此列表项组件,请为您的大型列表创建一个副本,并使用尽可能少的逻辑并尽可能少嵌套.

使用轻组件

组件越重,渲染速度越慢.避免沉重的图像(使用裁剪版本的列表项,尽可能小).与您的设计团队交谈,在列表中使用尽可能少的效果,互动和信息.将它们保存到项目的详细信息中.

使用shouldComponentUpdate

对组件实施更新验证.React的PureComponent主要用于没有时间思考的时候.如果您正在阅读本文,那么您确实有时间,因此,请为列表项组件创建最严格的规则.如果您的列表足够简单,您甚至可以使用

shouldComponentUpdate() {
  return false
}
Run Code Online (Sandbox Code Playgroud)

  • 在大多数情况下,这看起来像是用于优化 FlatList 配置的 React-Native 文档的副本。我认为你应该链接原始文档https://facebook.github.io/react-native/docs/optimizing-flatlist-configuration (3认同)
  • @Tyler 如果你深入挖掘,你会发现文档的这一部分 [是基于我的文章的 PR](https://github.com/facebook/react-native-website/pull/970)。所以这篇文章就是这一切的起源。 (3认同)