当我滚动平面列表时,内存使用率越来越高,并且在我停止滚动时没有释放内存(React Native)

时间:2018-09-26 04:53:18

标签: reactjs react-native memory react-native-flatlist react-native-sectionlist

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

我知道这里有一些相关的问题,但是我尝试了许多解决方案,但是都没有用。

例如,

1。 我使用了Pure.component或shouldcomponentUpdate

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

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

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

1 个答案:

答案 0 :(得分:3)

disableVirtualization={true}基本上会关闭FlatList提供的虚拟化功能,因此,如果不考虑内存,我不建议您这样做。因此,我将从删除此道具开始。

然后,我将调查问题是否在于存在太多项目(因此需要过多的RAM才能将它们保留在UI中),或者项目中是否存在内存泄漏(因此即使它们从用户界面中删除,它们仍然占用内存)

FlatList的windowSize控制将保留呈现多少“不可见”项目。如果将windowSize设置为“ 1”,则仅呈现可见项(尝试并查看滚动FlatList时发生的情况)。 windowSize为“ 21”(默认值)将呈现可见项,并在可见区域的左侧和右侧(或顶部和底部)加上10个“窗口”。因此,如果窗口大小为1000像素,则当前不可见但距离可见区域小于10000像素的所有项目将由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和类似的东西)可能会造成泄漏,而这些泄漏在发行版本中实际上并不存在。