Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory usage is getting higher and higer while I am scrolling Flatlist and memory is not released when I stop scrolling (React Native)

I am using Flatlist and SectionList in my react native project and I have 300+ rows of data. However, I found a serious problem which is when I keep scrolling down and up, the memory usage is getting higher and higher. How can I solve this problem? Or how can I release the memory?

I know there are some related questions on here but I've tried many solutions and none of them works.

For examples,

1. I used Pure.component or shouldcomponentUpdate

2. I used some props of Flatlist and SectionList

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

Is there any other solutions can help me solve the problems? Thanks a lot!

like image 408
Lynn Avatar asked Sep 26 '18 04:09

Lynn


1 Answers

disableVirtualization={true} basically turns off the virtualization features that FlatList offers, so I don't recommend it if memory is a concern. So I'd start by removing this prop.

Then, I'd investigate if the problem is the that there are too many items (so it takes too much RAM to keep them in the UI), or if there is a memory leak in your items (so even after they are removed from the UI they still consume memory)

FlatList's windowSize controls how many "invisible" items will be kept rendered. If you set windowSize to "1", only the visible items will be rendered (try that and see what happens when you scroll the FlatList). A windowSize of "21" (the default value) will render the visible items, plus 10 "windows" to the left and to the right (or the top and to the bottom) of the visible area. So, if the window measures, let's say 1000px, any items that are invisible right now but are less than 10000px from the visible area will be rendered by the FlatList ahead of time.

This is how I would approach the problem:

  • First, I would set windowSize to a very large value (e.g. 100) to make sure all the 300+ rows will be kept in memory. You can open the app and wait a while until all items have been rendered (if you have 300+ items and a maxToRenderPerBatch set to 2, this means FlatList will take 150+ "cycles" to finish rendering everything, so it may take a while. You can also, only for this experiment's sake, set initialNumToRender to a very high number (e.g. 1000) so that when the list renders you know it is already fully rendered. But likely the app will freeze for several seconds before this happens). Once the list is all there, see how much memory your app is using. In this scenario, scrolling up and down shouldn't increase memory usage, because, well, everything is already in the UI :-). Take note of this amount of memory as it will be your baseline.
  • Second, I would set windowSize to the smallest number possible (e.g. 1). Now, when you open the screen that has this huge amount of data React will only render what's visible in the screen. The use of memory should be much smaller than in the previous case. However, as you scroll, React will continously destroy and create new UI elements due to the restricted windowSize. If the more you scroll, the more memory is used (and it never goes back, even when you stop scrolling for a while), then there is probably a memory leak in your visual components which needs to be fixed. If this is true, slowly scrolling all the way to the bottom of the list and slowly scrolling all the way back to the top could even result in more RAM being used than in the first case.

Memory leaks can be tough to find, so I'm hoping simply adjusting the windowSize and a few other settings will give the results you need. If there are memory leaks, this is an interesting article I've read recently: https://blog.swmansion.com/hunting-js-memory-leaks-in-react-native-apps-bd73807d0fde

Also, avoid checking for RAM usage using debug builds: not only they use more memory, debug facilities (like console.log and things like that) may create leaks that don't actually exist in release builds.

like image 130
rsalmeidafl Avatar answered Oct 23 '22 03:10

rsalmeidafl