当我滚动 Flatlist 时,内存使用率越来越高,当我停止滚动时内存没有释放(React Native)

Posted

技术标签:

【中文标题】当我滚动 Flatlist 时,内存使用率越来越高,当我停止滚动时内存没有释放(React Native)【英文标题】:Memory usage is getting higher and higer while I am scrolling Flatlist and memory is not released when I stop scrolling (React Native) 【发布时间】:2019-03-01 18:51:40 【问题描述】:

我在我的 react native 项目中使用 Flatlist 和 SectionList,我有 300 多行数据。但是,我发现了一个严重的问题,即当我不断向下和向上滚动时,内存使用率越来越高。我怎么解决这个问题?或者如何释放内存?

我知道这里有一些相关的问题,但我尝试了很多解决方案,但没有一个有效。

例如,

1。 我使用 Pure.component 或 shouldcomponentUpdate

2。 我使用了一些 Flatlist 和 SectionList 的 props

initialNumToRender=9
windowSize=10
maxToRenderPerBatch=2
removeClippedSubviews=true
disableVirtualization=true
getItemLayout=this.getItemLayout
keyExtractor=(item, index) => item[0]
extraData=this.state

还有其他解决方案可以帮助我解决问题吗?非常感谢!

【问题讨论】:

在行项目上尝试overflow: 'hidden' 样式。 嘿,你有什么解决办法吗? 【参考方案1】:

disableVirtualization=true 基本上关闭了 FlatList 提供的虚拟化功能,所以如果内存是一个问题,我不推荐它。所以我会先移除这个道具。

然后,我会调查问题是否是项目太多(因此需要太多 RAM 才能将它们保留在 UI 中),或者您的项目是否存在内存泄漏(所以即使在它们之后从 UI 中删除它们仍然会消耗内存)

FlatList 的 windowSize 控制将保持呈现多少“不可见”项。如果将 windowSize 设置为“1”,则只会呈现可见项目(尝试一下,看看滚动 FlatList 时会发生什么)。 “21”(默认值)的 windowSize 将呈现可见项目,再加上可见区域左侧和右侧(或顶部和底部)的 10 个“窗口”。所以,如果窗口测量,比如说 1000px,任何现在不可见但距离可见区域小于 10000px 的项目将被 FlatList 提前渲染。

这就是我解决问题的方法:

首先,我将 windowSize 设置为一个非常大的值(例如 100),以确保所有 300 多行都保存在内存中。您可以打开应用程序并等待一段时间,直到所有项目都被渲染(如果您有 300 多个项目并且 maxToRenderPerBatch 设置为 2,这意味着 FlatList 将需要 150 多个“周期”来完成所有内容的渲染,因此可能需要一段时间. 您也可以,仅出于本实验的目的,将 initialNumToRender 设置为一个非常高的数字(例如 1000),以便在列表呈现时您知道它已经完全呈现。但在此发生之前,应用程序可能会冻结几秒钟)。一旦列表全部存在,请查看您的应用程序正在使用多少内存。在这种情况下,上下滚动不应该增加内存使用量,因为一切都已经在 UI 中了 :-)。请记下此内存量,因为它将作为您的基准。 其次,我会将 windowSize 设置为可能的最小数字(例如 1)。现在,当你打开包含大量数据的屏幕时,React 只会渲染屏幕中可见的内容。内存的使用应该比前一种情况小得多。然而,当你滚动时,由于 windowSize 的限制,React 会不断地销毁和创建新的 UI 元素。如果您滚动的次数越多,使用的内存就越多(并且它永远不会返回,即使您停止滚动一段时间也是如此),那么您的可视组件中可能存在内存泄漏,需要修复。如果这是真的,缓慢滚动到列表底部并缓慢滚动到顶部甚至可能导致使用比第一种情况更多的 RAM。

内存泄漏可能很难找到,所以我希望只需调整 windowSize 和其他一些设置即可获得所需的结果。如果有内存泄漏,这是我最近读到的一篇有趣的文章:https://blog.swmansion.com/hunting-js-memory-leaks-in-react-native-apps-bd73807d0fde

此外,请避免使用调试版本检查 RAM 使用情况:不仅它们使用更多内存,调试工具(如 console.log 等)可能会造成发布版本中实际上不存在的泄漏。

【讨论】:

以上是关于当我滚动 Flatlist 时,内存使用率越来越高,当我停止滚动时内存没有释放(React Native)的主要内容,如果未能解决你的问题,请参考以下文章

使用标题呈现时,React Native FlatList 超出屏幕范围

react-native ScrollView 嵌套 FlatList滚动

当 SectionList/Flatlist 滚动/渲染项目时 UI 线程似乎被阻塞(React Native)

React-Native 使用 Flatlist 滚动到顶部

排毒:“找不到 UI 元素。”尝试滚动 FlatList 时

在 FlatList(和 ScrollView)中锁定滚动位置