我的代码将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秒,这对用户来说很烦人.我该怎么做才能更快?

推荐答案

Edit Dec 20 '19:关于这个答案的信息成为了official docs个答案的一部分.你应该go 看看!


Edit May 26 '18:这个答案变成了bigger and more complete post on github


如果您遵循this thread,您将看到react的团队已经意识到了这个性能问题.

在这个问题上没有什么灵丹妙药,你必须考虑每一种方法的权衡,你认为对你的观众来说是一种很好的体验.但幸运的是,你可以try 一些调整来提高你的FlatList分.


Terms and meanings

有很多术语(关于docs个或一些问题)一开始让我感到困惑.所以,让我们从一开始就把这件事解决掉.

  • VirtualizedListFlatList背后的组成部分,是React Native对"virtual list"概念的实现.

  • Performance,在这种情况下,意味着一个平滑(而不是起伏)的滚动(以及在列表中或列表外的导航)体验.

  • Memory consumption,在这个上下文中,是关于你的列表的多少信息被存储在内存中,这可能会导致应用程序崩溃.

  • Blank areas意味着VirtualizedList无法足够快地呈现您的项目,因此您可以在列表的一部分输入未呈现的组件.

  • Window这里不是视口,而是应该渲染项目的区域大小.


Props

提高FlatList分的一个方法是调整props .下面是一个可以帮助你解决这个问题的props 列表.

RemoveClipped子视图

您可以将RemoveClipped子视图props 设置为true,这将卸载窗口外的组件.

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

Trade offs:请注意,此实现可能存在错误,例如,如果您在不会卸载的组件(如导航路由)上使用它,就会丢失内容.

maxToRenderPerBatch

你可以设置maxToRenderPerBatch={number},这是一个VirtualizedListprops ,可以直接传递到FlatList.有了它,您可以控制每批渲染的项目数量,这是每个滚动上渲染的下一个项目块.

Win:设置更大的数字意味着滚动时视觉空白区域更少(填充率越高).

每批多Trade offs:个项目意味着JavaScript性能降低,这意味着响应能力降低(单击一个项目并打开详细信息).如果你有一个静态的、非交互式的列表,这可能是最好的 Select .

初始化NumTorender

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

Win:您可以将该值设置为覆盖每个设备屏幕的精确项目数.在呈现列表组件时,这会大大提高性能.

Trade offs:设定低初始化NumTorender时,最有可能看到空白区域.

窗口大小

你可以设定窗口大小={number}.此处传递的数字是一个测量单位,其中1等于视口高度.默认值为21,即上方10个视口,下方10个视口,中间一个视口.

Win:如果你主要担心的是性能,你可以设置一个更大的窗口大小,这样你的列表就会运行顺畅,并且有更少的空白.如果你主要担心内存消耗,你可以设置一个更低的窗口大小,这样你的渲染列表就会更小.

Trade offs:对于更大的窗口大小,你将有更大的内存消耗.对于较低的窗口大小,你将有较低的性能和更大的变化,看到空白区域.

法律实施

This prop,如果是真的,让你的FlatList依赖于老的ListView,而不是VirtualizedList.

Win:这肯定会让你的列表表现得更好,因为它会移除虚拟化,并一次呈现你的所有项目.

Trade offs:你的内存消耗达到顶峰,一个包含复杂项目的大列表(Trade offs:+)很可能会使你的应用程序崩溃.

禁用虚拟化

你会看到人们在一些问题上提倡使用这个props .但是this is deprecated now.它曾经做过类似于法律实施的事情.


List items

还有一些双赢的策略涉及到你的列表项组件.他们经常被VirtualizedList管理,所以他们需要更快.

使用简单的组件

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

使用轻组件

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

使用shouldComponentUpdate

对组件进行更新验证.React的PureComponent主要用于你没有时间思考的时候.如果你正在读这篇文章,你确实有时间,所以,为你的列表项组件创建最严格的规则.如果你的列表足够简单,你甚至可以使用

shouldComponentUpdate() {
  return false
}

React-native相关问答推荐

如何渲染一个 svg 以在不同的窗口大小下动态地看起来相同?

自定义单选按钮在react native 中不起作用

为什么当键盘出现在react native 时我的按钮会上升?按钮视图位置是绝对的?

如何在react-navigation 中将drawer抽屉放在标题上?

_react2.default.PropTypes.function 未定义

在react-native 模块库中找不到 ios 框架头文件

使用带有 react-native 的 WebView 设置用户代理

xcrun:错误:SDK "iphoneos" cannot be located

如何使用react钩子设置状态数组

Xcode 设备不可用,未找到运行时配置文件

Jest 的配置在更新到 26.x 后抛出type ErrorHandler = (error: mixed, isFatal: boolean) => void

是否可以在 react-native 的构造函数中调用异步函数?

更改按钮 colored颜色 onPress(切换功能)

React Native如何将this.setState更改传递给父级

如何在 react-native 中为在后台杀死的 android 应用程序保持状态

I18nManager.forceRTL 不会在首次应用加载时应用更改

开始滚动时使 TouchableOpacity 不突出显示元素

为什么我收到警告:函数作为 React 子级无效?

React Native:无法解析模块 fs

React-Native 水平滚动视图分页:预览下一页/卡片