React Native中VirtualzedList更新慢时返回对象的含义

Meaning of the object returned when VirtualzedList is slow to update in React Native

我正在为我的大学校园制作一个社交网络应用程序。我正在使用 React Native。现在我正在使用 Redux 维护我的应用程序状态,使用 React-redux 将状态绑定到各种 React 组件,使用 redux-thunk 进行异步 API 调用以获取和 post 数据。我收到的任何数据,在将其提交到 Redux 存储之前对其进行规范化。我面临的一个主要问题是,每当我开始滚动浏览应用程序的 "Feed" 时,我都会收到一条警告:

VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. Object {
  "contentLength": 6298,
  "dt": 4840,
  "prevDt": 7619,
}

我想知道上面对象中的各种键值对到底是什么意思。另外,为了获得良好的用户体验,这些值大约应该是多少。

注意:我正在使用 FlatList 呈现单独的 post 个 Feed。

简要概述

  • dt 是最后两次内部 onScroll 事件触发之间的时间,这是对渲染时间的间接测量;
  • prevDt是预先一个周期的相同测量;
  • contentLength 是呈现内容的主要尺寸(宽度或高度)。

这些是间接的,但是很好的经验法则衡量你的渲染逻辑被分割的合理程度。如需更深入的了解,请参阅下文。


FlatList 内部结构

React Native 的 FlatList is internally backed by VirtualizedList. The latter uses the onScroll event of its ScrollView 用于衡量性能指标。

主要指标 dtprevDt 衡量给定 ScrollViewonScroll 事件触发的频率。两者都是通过在 onScroll 事件触发时存储当前时间戳并将其与上次存储的值进行比较来衡量的。 dt 是当前的 delta,prevDt 是前一个事件触发时测得的 delta。

以简化的方式,此交互如下所示,您可以查看完整代码over here

onScroll(event) {
  const timestamp = event.timeStamp;
  const dt = timestamp - this.previousTimestamp;
  // ...
  this.previousTimestamp = timestamp;
}

这衡量了 React Native 的 Javascript 端从本机端接收事件的频率。这是一种间接但非常有效的方法来衡量您的列表是否需要很长时间才能在本机端呈现。

contentLength 是呈现内容的大小,通常与呈现所述内容所花费的时间直接相关。如果您的内容是水平的,则它是您呈现的内容的高度,对于垂直视图,它是宽度。

onScroll(event) {
  // ...
  const contentLength = event.nativeEvent.contentSize.height;
  const visibleLength = event.nativeEvent.layoutMeasurement.height;
  // ...
}

警告

当满足以下所有条件时抛出所述警告(参见 original code):

  • 当前渲染时间超过 500 毫秒(这意味着 dt > 500);
  • 之前的渲染也花费了 500 多毫秒 (prevDt > 500);
  • 并且呈现的内容比实际屏幕尺寸大五倍多 (contentLength > 5 * visibleLength)。

简而言之,当渲染时间很长并且一次渲染大量内容时会抛出错误。为了获得良好的用户体验,可以假定推荐值因此低于所示值。

如何减少这些问题超出了本答案的范围,但抛出的错误为您提供了一些很好的起点(React.PureComponent, shouldComponentUpdate() 等)。