Lists at Scale: FlatList, SectionList and FlashList
Rendering a thousand-row list by mapping the whole array into native views works perfectly in a demo and falls over the moment real data arrives — every row mounts as an actual native view immediately, memory climbs with the dataset size, and the initial render blocks the JS thread for however long a thousand `renderItem` calls take. Native list widgets on iOS and Android never did this either; a real list only ever materializes the rows currently near the viewport and recycles the views for rows that scroll away, which is exactly the discipline React Native's list components exist to bring to JavaScript-rendered content.
`FlatList` is the built-in answer, `SectionList` extends it with grouped, sectioned data, and `FlashList` is a third-party replacement built around a fundamentally different recycling strategy for the cases where `FlatList`'s windowing still is not fast enough. Choosing between them, and configuring whichever one you pick correctly, is the difference between a list that feels instant and one that visibly hitches every time new rows scroll into view.
Analogy🏏Cricket
🏏 Think of it like cricket: A stadium seating fifty thousand people for a World Cup final does not print, laminate, and physically hand out fifty thousand individual printed scorecards the moment the gates open — the big screen shows only the current over's information, refreshed continuously, while the vast majority of the ground's capacity is simply not rendering detailed information to anyone at any given moment because nobody is looking at all fifty thousand seats' worth of detail simultaneously. The screen's operators built the display around exactly this principle: render what's currently in view, in detail, and don't waste rendering budget on seats and overs nobody is actually looking at right now. If the venue instead tried to display full ball-by-ball detail across every screen in the stadium simultaneously for the entire match's history at once, the system would be overwhelmed by information nobody could actually consume at that instant. Just as the big screen renders only what's currently relevant to what a viewer is looking at, a list component should render only the rows currently near the viewport, not the entire dataset at once. Just as recycling the same screen space for over after over avoids building new infrastructure for every over that passes, a list recycling the same view instances for rows scrolling in and out avoids the cost of mounting a fresh native view for every single row in a thousand-row dataset. The insight is that a system handling scale does not do more work as the dataset grows — it does the same bounded amount of work near the viewport, regardless of whether the underlying dataset is fifty rows or fifty thousand.
🏏 Showing the Cricket analogy — a Cricket version isn’t available for this concept yet.