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

时间:2017-12-06 16:23:16

标签: javascript react-native react-native-android react-native-flatlist

我的代码获取Json数据到数组使用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>
    );
  }

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

2 个答案:

答案 0 :(得分:14)

这个答案变为bigger and more complete post on github

如果您按照this thread进行操作,您会发现反应小组已经意识到此性能问题。

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

术语和含义

有很多术语(docs或某些问题)一开始让我感到困惑。所以,让我们从头开始解决这个问题。

  • VirtualizedList FlatList背后的组件,是React Native对&#39; virtual list&#39;的实现。概念

  • 效果,在此上下文中,暗示了一种平滑(非波动)的滚动(以及列表中的导航或导出)。

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

道具

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

removeClippedSubviews

您可以将removeClippedSubviews道具设置为true,从而卸下窗口外的组件。

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

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

maxToRenderPerBatch

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

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

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

initialNumToRender

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

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

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

windowSize

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

赢:如果您主要担心性能问题,可以设置更大的windowSize,这样您的列表就可以顺利运行并占用更少的空白。如果您主要担心内存消耗,可以设置较低的windowSize,以便渲染列表更小。

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

legacyImplementation

This prop,如果为真,请让FlatList依靠较旧的ListView,而不是VirtualizedList

赢:这会使您的列表确实表现更好,因为它会删除虚拟化并立即呈现所有项目。

权衡利弊:您的内存消耗量达到顶峰并且很有可能包含复杂项目的大型列表(100+)会使您的应用程序崩溃。 它还会发出上述调整不起作用的警告,因为您现在已经在ListView上了。

disableVirtualization

你会看到人们在某些问题上建议使用这个道具。但是this is deprecated now。这用于执行与legacyImplementation类似的操作。

列出项目

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

使用简单组件

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

使用灯光组件

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

使用shouldComponentUpdate

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

shouldComponentUpdate() {
  return false
}

答案 1 :(得分:2)

以下是优化平板列表的一些改进措施:

  1. 分页
    • 您可以在后端对数据进行分页,并在滚动接近结束时重新获取数据。 onEndReachedonEndReachedThreshold可以为您提供帮助。
  2. 将您的React Native版本更新为49或最新版本
    • Fiber 16具有惊人的性能提升,使一切运行得更快更顺畅
  3. PureComponent用于渲染项目
    • PureComponent可以改善组件的渲染和内存使用,创建纯色渲染项可以提供更好的性能体验
  4. 定义getItemLayout道具
    • 它改进了项目呈现,因为React以前会知道它的布局定义
  5. 希望有所帮助