Why FlatList Falls Short

React Native's FlatList component handles scrollable item rendering without forcing developers to manage memory or layout directly. In practice, though, it struggles to keep up on a wide range of devices, often producing visible frame drops and blank cells during fast scrolling. Those artifacts are the symptoms of a deeper issue: FlatList generates new views from scratch on every update, which becomes costly as list complexity grows.

Shopify's React Native Foundations team set out to solve this with FlashList, a list component designed as a drop-in replacement for FlatList that targets three specific goals: smooth scrolling at 60 FPS or greater even on low-end hardware, elimination of blank cells during scroll, and a developer experience familiar to anyone who already knows FlatList.

Building on RecyclerListView—Carefully

The team evaluated RecyclerListView, a third-party library known for strong performance with large datasets. While the library delivers good results when configured correctly, it demands a significant investment from developers. Accurate predicted size estimates for each item are essential; incorrect estimates degrade the UI. Additionally, RecyclerListView performs its entire layout in JavaScript, which can introduce visible glitches.

Rather than start from zero, FlashList builds on RecyclerListView's foundation while addressing its usability problems. The key shift was moving part of the layout operations to native code. This reduces the glitches that occur when RecyclerListView receives inaccurate size estimates.

Recycling Cells and Reducing Buffers

FlashList's core performance win comes from recycling cells. Instead of constructing fresh views on every update, it reuses already allocated views and refreshes their contents. Combined with native-side layout work, this approach keeps the UI thread responsive.

The results are measurable. Where FlatList typically shows frame drops even on simple lists, FlashList sustains 60 FPS or better—even on low-end Android devices. The team adopted a metrics-based approach, focusing on hard numbers like blank cell counts and frame rates rather than subjective impressions, and prioritized testing on cost-effective devices to ensure performance carried over to high-end hardware.

Simple list comparison (Twitter clone) @ShopifyEng FlashList vs @reactnative FlatList
on a low end Android

On the left, trying my best to scroll the FlatList 😅: the scroll locks because JS is dead! ☠️
Right side: no locking! ✅

Will post #performance metrics next week 📈 pic.twitter.com/IW8Ly5c1jD

— Alexandre Moureaux (@almouro) July 1, 2022
Comparison between FlatList and FlashList via Twitter (note this is on a very low-end device)

Memory utilization gets the same treatment. Consider a Twitter-like feed with 200–300 items per page: FlatList renders a large initial batch to stay ahead of scrolling. FlashList needs a much smaller buffer—250 pixels by default—which cuts memory footprint, speeds up load times, and keeps the app more responsive. Faster render times also mean the list can keep pace with fast scrolling, eliminating the blank-item problem.

Drop-In Upgrade Path

Switching from FlatList to FlashList requires minimal code changes: rename the component and, optionally, add the estimatedItemSize prop. The API is nearly identical, so developers already comfortable with FlatList can get productive immediately.

Example of FlashList usage.

Beyond the standard props, FlashList ships with features addressing common developer pain points:

  • getItemType: improves render performance for heterogeneous lists (e.g., text versus image items) by maintaining separate recycling pools per item type.
  • Flexible column spans: grid layouts can assign each item an explicit column span or a size estimate via overrideItemLayout.
  • Performance metrics: because much of the layout logic runs natively, FlashList can expose metrics like blank-area counts and FPS for troubleshooting, detailed in this guide.

The fact that FlashList's API is exactly the same as FlatList is an application that will make it very easy to move your project to FlashList. In addition, they have added a few features, for example: You can see how long it takes to load the list thanks to the onLoad feature. pic.twitter.com/Izkwyte2Xj

— V. Furkan Güner (@vfurkanguner) July 4, 2022

Teams inside Shopify have already adopted FlashList. Shopify Mobile uses it as the default list component, while the Shop team migrated search over to it. POS is also running FlashList in production.

More Than a Faster FlatList

FlashList also unlocks capabilities that FlatList doesn't offer. For example, scrollToIndex can target an index outside the current viewport, which enables use cases like a calendar feed where users jump quickly between dates.

Getting Started

FlashList is available now. The project provides several resources to support adoption:

The team continues to address known issues and invites feedback via the GitHub repository. A follow-up post covers lessons learned from open-sourcing FlashList.