SECRET OF CSS

Meet FlashList: A better alternative to FlatList for React Native | by Burak Erdem | Sep, 2022


A brief guide to the advantages of switching

0*742pGmystg6Pi5Ve 300w
Photo by Glenn Carstens-Peters on Unsplash

Ever since I started to develop with React Native, pretty sure like everyone else, I ran into this warning at least a dozen times:

VirtualizedList: You have a large list that is slow to update — make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. {“dt”:13861,“prevDt”:1498372326027,“contentLength”:6624}

Seems familiar, right? This usually happens when we fill up a FlatList with many items which are not just a static image or text but rather with components that have some animations or other interactions in them.

The FlatList here simply says it can’t handle the list to render smoothly. You can always ignore it as a warning, but it doesn’t mean it will go away. I wish we could live in a world like this.

0*RglPAfnli50hY3ey 300w
Photo by JESHOOTS.COM on Unsplash

Before jumping to solutions, let’s dig into this message and find out what those numbers are:

FlatList, which is based on ScrollView, uses a listing interface called VirtualizedList. Under the hood, VirtualizedList utilizes a rendering API responsible for displaying an enumerable list of items in the form of scroll. Maybe we don’t notice it because we have the latest iPhone, and we do it through Instagram posts all day smoothly. The scrolling action is a huge process-intensive task for a mobile application because not only does it require pre-rendering for the next upcoming content from the top or down, but it also has to display this content with a sliding effect when it’s in the viewport.

These intensive calculations are called “batches,” and any batch size over the previous one is called “delta.” So the numbers are dt(delta), prevDt(previous delta) and expressed in timestamps, meaning the time passed between batches. The last number is contentLength, which is the whole content size in React Native’s unitless(!) unit. Whenever any delta value passes 500ms and contentLength exceeds five times the viewport size, this error gets triggered. That’s the limit for VirtualizedList to work properly.

So what can you do about it? You can search the internet or take the reference of FlatList in React Native’s official website and come up with some techniques that optimize the rendering process. Those include using initialNumToRender or removeClippedSubviews props, maybe memoizing the item component or making it pure. Most of the time, whatever you use will make this message go away, and you’ll be just fine.

But…

Even if it seems OK, if your project runs on low-end devices, especially the Android ones, you may still get this error. Because it’s simply those techniques that also need to make some calculations to work it out. That being said, what we need to do, is to redirect this burden of processes into some other thread. Maybe, and why not, the UI, right?

Meet FlashList! A FlatList alternative that runs on UI thread and, as they claim on their website, it runs 10x faster on JS and 5x faster on JS thread. Even considering only half the improvement — these are really great performance boosts.

1*DMkczGr5C2noU1Vta u2yA

To use it, you only need to install FlashList using this command:

yarn add @shopify/flash-list

pod install if you need to replace your existing <FlatList> with <FlashList>. That’s it!

Yes, FlashList is extremely easy to use because it has the same props as FlatList. That means data, renderItem, ListEmptyScrollComponent, and so on. The only difference is that it uses RecyclerView instead of VirtualizedList as the underlying component, the performance props we mentioned above are unnecessary. Instead, there are other performance and diagnostic props that you can check out at https://shopify.github.io/flash-list/docs/usage.

Most notably, estimatedItemSize which you provide your single component’s height. If every item on your list has an equal size, it’ll be super fast because FlashList doesn’t need to recompute items’ sizes individually. If it’s flexible, you can take the sum of your elements’ height and provide it to this prop.

On the other hand, if you’re targeting low-end devices, you may need additionally tweak the other props, such as getItemType or overrideItemLayout. The “light component” logic still applies in FlashList, so you can check out https://shopify.github.io/flash-list/docs/fundamentals/performant-components to optimize your components.

I personally didn’t use this library on production so far, but I did some tests on my old Samsung S5 phone, and I can tell the scrolling performance becomes much better when I use FlashList. Previously there were noticeable blank areas while I was scrolling fast, and they were all gone when I switched to it.

You can go ahead and check the library at https://shopify.github.io/flash-list/ and easily replace your existing FlatLists with this one. I’m sure you’ll notice the increase in performance, especially if you’re using animations or complex layouts in your items.

Thanks for reading!



News Credit

%d bloggers like this: