Skip to content

Performance

Legend List is very optimized by default, so it may already be working well without any configuration. But these are some common ways to improve your list behavior.

Itโ€™s important to provide an estimatedItemSize (if items are the same size or all dynamic sizes) or getEstimatedItemSize (if items are different known sizes). Legend List uses this as the default item size, then as items are rendered it updates their positions with the actual size. So getting this estimate as close as possible to the real size will reduce layout shifting and blank spaces as items render. If not provided it will use 100px as the default.

The onItemSizeChanged event can also help with your estimations - it will be called whenever an itemโ€™s size changes. So you can use it to log what the actual rendered size is to adjust your estimates.

Use keyExtractor Prop

keyExtractor?: (item: T, index: number) => string;

The keyExtractor prop lets Legend List save item layouts by key, so that if the data array changes it can reuse previous layout information and only update the changed items. Without keyExtractor, item sizes will reset to their default whenever data changes. So it is very recommended to have a keyExtractor if data ever changes. If your items are a fixed size, providing a keyExtractor that returns the index will tell it to reuse size information.

Recycling List Items

recycleItems?: boolean // default: false

Legend List has an optional recycleItems prop which enables view recycling. This will reuse the component rendered by your renderItem function. This can be a big performance optimization because it does not need to destroy/create views while scrolling. But it also reuses any local state, which can cause some weird behavior that may not be desirable depending on your app. But see the next section for recycling hooks to make that easier.

So there are some tradeoffs with recycling:

  • ๐Ÿ‘ If you have items with no state then recycling should be great
  • ๐Ÿ‘Ž If you have simple items with complex state then it may be more trouble than itโ€™s worth
  • ๐Ÿ‘ If you have heavy items with complex state then working around the state recycling may be worth it for the performance gains

Estimate Item Sizes

estimatedItemSize?: number;
getEstimatedItemSize?: (index: number, item: T) => number;
onItemSizeChanged?: (info: {
size: number;
previous: number;
index: number;
itemKey: string;
itemData: ItemT;
}) => void;

Set DrawDistance Prop

drawDistance?: number

The drawDistance (defaults to 250) is the buffer size in pixels above and below the viewport that will be rendered in advance. So for example if your screen is 2000px tall and your draw distance is 1000, then it will render double your screen size, from -1000px above the viewport to 1000px below the viewport.

This can help reduce the amount of blank space while scrolling quickly. But if your items are computationally expensive, it may reduce performance because more items are rendering at once. So you should experiment with it to find the most optimal behavior for your app.

Use waitForInitialLayout Prop

waitForInitialLayout?: boolean

If the size of your list items differs significantly from the estimate, you may see a layout jump after the first render. If so, the waitForInitialLayout prop solves that by delaying displaying list items by one frame so they start at the correct position.