2019 年 12 月 20 日编辑:有关此答案的信息已成为 official docs 的一部分。你应该去看看!
2018 年 5 月 26 日编辑:这个答案变成了 bigger and more complete post on github
如果你关注this thread,你会发现 react 的团队已经意识到了这个性能问题。
对于这个问题没有灵丹妙药,您必须考虑每种方法的权衡以及您认为对您的受众来说是一种良好体验的方式。但幸运的是,您可以尝试进行一些调整并改进您的FlatList。
术语和含义
起初使用的很多术语(在docs 或某些问题上)让我感到困惑。所以,让我们从一开始就解决这个问题。
-
VirtualizedList 是 FlatList 背后的组件,是 React Native 对“virtual list”概念的实现。
-
性能,在这种情况下,意味着平滑(不断断续续)滚动(以及在列表中导航或导航)体验。
-
内存消耗,在这种情况下,是指有多少关于您的列表的信息存储在内存中,这可能会导致应用崩溃。
-
空白区域表示 VirtualizedList 无法以足够快的速度呈现您的项目,因此您在列表的一部分上输入了未呈现的组件。
-
窗口这里不是您的视口,而是应该呈现项目的区域的大小。
道具
改善FlatList 的一种方法是调整它的道具。以下是可以帮助您的道具列表。
removeClippedSubviews
您可以将 removeClippedSubviews 属性设置为 true,这会卸载窗口外的组件。
Win:这对内存非常友好,因为您总会有一个小渲染列表。
权衡:请注意,此实现可能存在错误,例如,如果您在不会卸载的组件(例如导航路线)上使用它,则会丢失内容。
它的性能也可能较低,在不太好的设备上为包含复杂项目的大型列表提供不连贯的滚动动画,因为它每次滚动都会进行大量的计算。
maxToRenderPerBatch
你可以设置maxToRenderPerBatch={number},这是一个VirtualizedList prop,可以直接传递给FlatList。有了这个,你可以控制每批渲染的项目数量,这是每次滚动渲染的下一个项目块。
赢:设置更大的数字意味着滚动时视觉空白区域更少(填充率更好)。
权衡:每个批次的项目越多意味着 JavaScript 性能越差,这意味着响应性越差(单击项目并打开详细信息)。如果您有一个静态且非交互式的列表,这可能是可行的方法。
initialNumToRender
您可以设置initialNumToRender={number}。这意味着要渲染的项目的初始数量。
赢:您可以将此值设置为每个设备的屏幕上的精确项目数。这可以在渲染列表组件时大大提升性能。
权衡:设置较低的initialNumToRender 时,您最有可能看到空白区域。
窗口大小
您可以设置windowSize={number}。此处传递的数字是一个测量单位,其中 1 等于您的视口高度。默认值为 21,即上方 10 个视口,下方 10 个视口,介于两者之间。
Win:如果您主要担心性能,您可以设置一个更大的windowSize,这样您的列表就会顺利运行,并且空白空间更少。如果你主要担心内存消耗,你可以设置一个较低的windowSize,这样你的渲染列表会更小。
权衡:对于更大的windowSize,您将有更大的内存消耗。对于较低的windowSize,您将有较低的性能和较大的看到空白区域的变化。
遗留实现
This prop,如果为真,则让您的 FlatList 依赖于旧的 ListView,而不是 VirtualizedList。
胜利:这肯定会让您的列表表现得更好,因为它消除了虚拟化并一次渲染所有项目。
权衡:您的内存消耗达到顶峰,很可能包含复杂项目的大列表(100 多个)会使您的应用程序崩溃。
它还会发出警告,指出上述调整将不起作用,因为您现在位于 ListView 上。
禁用虚拟化
你会看到人们在一些问题上提倡使用这个道具。但是this is deprecated now。这曾经做类似legacyImplementation的事情。
列出项目
还有一些涉及您的列表项组件的双赢策略。它们经常由 VirtualizedList 管理,因此它们需要快速。
使用简单的组件
您的组件越复杂,它们的渲染速度就越慢。尽量避免在列表项中出现大量逻辑和嵌套。如果您在应用程序中大量重用此列表项组件,请仅为您的大列表创建一个副本,并尽可能减少逻辑和嵌套。
使用灯光组件
组件越重,它们的渲染速度就越慢。避免使用沉重的图像(对列表项使用裁剪版本,尽可能小)。与您的设计团队交谈,在您的列表中使用尽可能少的效果、交互和信息。将它们保存到您的项目的详细信息中。
使用 shouldComponentUpdate
对您的组件实施更新验证。 React 的 PureComponent 主要是在你没有时间思考的时候使用的。如果您正在阅读本文,那么您确实有时间,因此,为您的列表项组件创建最严格的规则。如果您的列表足够简单,您甚至可以使用
shouldComponentUpdate() {
return false
}