Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FlatList renderItem is being called multiple times

Tags:

react-native

What am I doing ?

Trying to render a FlatList based on some items stored in state.data. A button is present which upon press appends a new item in state.data.

What is the problem ?

Upon pressing the button, I'm expecting that the renderItem to be called only state.data.length number of times whereas it's being called 2*state.data.length number of times. Also, this 2x behaviour is not always consistent and changes as state.data.length increases.

Ex: when state.data.length=3, then on initial render, number of times renderItem is called exactly 3 times which is same as the number of items in state.data and upon pressing button which appends a new item to state.data and now state.data.length=4 and renderItem is called 8 times i.e. 2*state.data.length times.

But, when state.data.length=11, then on initial render, renderItem is called exactly 21 times and upon pressing button which appends a new item to state.data and now state.data.length=12 and renderItem is called 23 times times which deviates from 2*state.data.length behaviour.

enter image description here

What am I expecting ?

renderItem to be called only state.data.length number of times on initial and subsequent renderings.

What I've tried ?

  1. Created a new project from scratch to test this behaviour with no luck.
  2. Made component inside renderItem PureComponent. Still the same behaviour as mentioned.
  3. Made a CodeSandbox at https://codesandbox.io/s/react-native-nn73t with react-native-web with the same behaviour as before. Please refer this sandbox for the code.
  4. Using props such as maxToRenderPerBatch, initialNumsToRender etc but to no avail either. Though using them with relatively large state.data does bring down the number of times renderItem is called but it's still not that great decrease.
  5. Referred similar questions but couldn't get much clarity
    • FlatList renderItem is called multiple times>
    • FlatList onEndReached being called multiple times

The real issue I'm facing is when I'm trying to render chat messages (fetching through API call and setting it inside the state) inside a FlatList. Right now there are about ~200 messages for which the renderItem is being called in a range of 800-1200 times which is taking a hit on the performance.

Is this behaviour which is deviating from my expectation expected ? If yes, then what's the logic behind this. If no, then what am I doing wrong here ?

like image 277
parichay28 Avatar asked Oct 31 '19 21:10

parichay28


People also ask

What is renderItem in FlatList?

renderItem({ item, index, separators }); Takes an item from data and renders it into the list.

How do you optimize a FlatList performance?

The more complex your components are, the slower they will render. Try to avoid a lot of logic and nesting in your list items. If you are reusing this list item component a lot in your app, create a component only for your big lists and make them with as little logic and nesting as possible.

What are the three key props used in a FlatList?

1. What are the three key props used in a FlatList? The Key props used in Flatlist are data, renderItem, and keyExtractor.


1 Answers

I went through your code and tried understanding your concern.

(renderItem ~ FlatList's prop ) Note :- when using flatlist your item of list should be pure component or should implement shouldComponentUpdate or else they will render a lot more time than expected

So the below points are keeping in mind that your flatlist item are implemented as stated.

  1. As per you concern of performance , there wont be any issue though the renderItem is called so many times . When you check how many times you item is actually rendered (by console.log() in your items render) that behaviour is as expected. so your items are not actually getting rendered it is only the renderItem in flatList that is called so many times.

try pressing (Add Item Immutably text) in the project link shared you will understand better. Check This project.

  1. So now the question which remains is why renderItem is called unexpected number of times and how to understand what is happening under the hood ?

Well even i am unaware of how things are implemented but as per what i read in docs i will just share few content that may help.

"In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate ands momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes."

and this is default value of few props which helps in controlling the tradeoff

maxToRenderPerBatch: 10,

onEndReachedThreshold: 2, // multiples of length

scrollEventThrottle: 50,

updateCellsBatchingPeriod: 50,

windowSize: 21, // multiples of length

for understanding more clearly , we need to understand how VirtualizedList is implemented. I will surely update this answer after digging more.

like image 128
RishabhRathod Avatar answered Sep 20 '22 12:09

RishabhRathod