5

I have a json of 10000 records which I need to show in a Flatlist.I am using a virtualized list which is working fine.Now I have certain filters which on click should filter out the json and re render the list with the new data.I am simply filtering out the data.

const filters = foo1;
const largeList = [{ id:1, foo:'foo1',bar:10 },{id:2, foo:'foo1',bar:20} ...]
const filteredList = largeList.filter(l=>l.foo === filters && l.bar > 10);

The filters are dynamic and this lags my application since it puts pressure in the UI thread.I have used InteractionManager.runafterinteractions() but that is not working in this situation. How do I do such expensive operations in the app without blocking the UI thread ?

sang
  • 109
  • 1
  • 1
  • 10
  • 2
    I'm afraid that's not possible in a way you'd need it to be done. Can't you do filtering on backend? – Samuli Hakoniemi Jul 05 '21 at 09:21
  • Thank you for the suggestion.Thats the problem.Client wants it in the app and its not possible to explain them :p . – sang Jul 05 '21 at 10:00
  • Never done that, but I'd try with a custom native module, that does the heavy work out of the UI thread ([here's a kickstart](https://github.com/brodybits/create-react-native-module)). [Here's another similar question](https://stackoverflow.com/questions/54588529/how-to-run-time-expensive-code-in-react-native) – Maen Jul 06 '21 at 13:50

1 Answers1

3

If you can't delegate the filter to your backend, the best way to achieve better performance is replacing .filter with a for loop.

There are a lot of pages online demonstrating that the for loop is much faster than array functions. (https://javascript.plainenglish.io/are-for-loops-better-than-arrays-filter-or-foreach-methods-f54b6880d201)

Moreover, you need to evaluate a better configuration of your Flatlist:

removeClippedSubviews: If true, views that are outside of the viewport are detached from the native view hierarchy.

maxToRenderPerBatch: It is a VirtualizedList prop that can be passed through FlatList. This controls the amount of items rendered per batch, which is the next chunk of items rendered on every scroll.

updateCellsBatchingPeriod: While maxToRenderPerBatch tells the amount of items rendered per batch, setting updateCellsBatchingPeriod tells your VirtualizedList the delay in milliseconds between batch renders (how frequently your component will be rendering the windowed items).

pure component: Implement update verification to your components. React's PureComponent implement a shouldComponentUpdate with shallow comparison. This is expensive here because it needs to check all your props. If you want a good bit-level performance, create the strictest rules for your list item components, checking only props that could potentially change. If your list is basic enough, you could even use. (React.memo could be a good solution)

source: https://reactnative.dev/docs/optimizing-flatlist-configuration

Francesco Clementi
  • 1,874
  • 4
  • 13
  • 28
  • Thanks.Will replace and check the performance. – sang Jul 06 '21 at 12:10
  • 1
    Let me add that you should use a PureComponent in your renderItem function of Flatlist. Did you use React.memo? https://it.reactjs.org/docs/react-api.html#reactmemo – Francesco Clementi Jul 06 '21 at 12:36
  • Read my updated answer – Francesco Clementi Jul 06 '21 at 13:42
  • Can't use a pure component since it involves a lot of logic for list items.React memo is a good technique but can't use in dynamic large list.My question says more than 10k rows.I have used all of above solutions and come to conclusion that you can't just do this yet.Moving to native for now.Thanks anyways. – sang Jul 06 '21 at 15:21