
The ultimate guide to fast and scalable lists in React Native
How to display hundreds of elements in a mobile app without losing fluidity? In the world of React Native, lists are more than just scrolling data - they're about performance, control and user experience. Learn a modern approach to rendering lists and see why FlashList is becoming the new standard.

- 1. ScrollView
- 1.1. Characteristics of the ScrollView component
- 1.2. When to avoid ScrollView?
- 2. FlatList
- 2.1. FlatList characteristics
- 3. SectionList
- 3.1. Features of the SectionList component
- 4. VirtualizedList
- 4.1. Features of VirtualizedList
- 5. FlashList
- 5.1. FlashList features
- 5.2. Why choose FlashList?
- 6. Additional advantages of FlashList
- 7. Summary
- 8. FAQ – Frequently asked questions about lists in React Native
- 8.1. Does FlashList work with Expo?
- 8.2. How to test the performance of lists in React Native?
- 8.3. Does FlashList support horizontal lists?
- 8.4. How does FlashList handle dynamically updated data?
- 8.5. Does FlashList support animations during scrolling?
List rendering in mobile apps is one of the key issues affecting performance and user experience quality. There are several components available in the React Native ecosystem for efficient display of large data sets. Each solution differs in its approach to memory management, rendering strategy and performance optimization.
The article presents the most popular ways to render lists in React Native, discussing five key components: ScrollView, FlatList, SectionList, VirtualizedList and FlashList. Particular emphasis is placed on FlashList – a modern tool created by Shopify, designed specifically to smoothly handle very large data sets. The purpose of the text is to present the characteristics of each solution and to help choose the best component depending on the needs of the application.
1. ScrollView
ScrollView is a basic component in React Native for displaying scrollable views, where all content is rendered simultaneously in device memory. It is ideal for small amounts of data or static layouts, where fully loading all content does not negatively affect performance.
Unlike more advanced components such as FlatList or FlashList, ScrollView does not use virtualization – each element is fully rendered, regardless of whether it is currently visible on the screen.
Characteristics of the ScrollView component
- no virtualization: All elements are loaded and stored in memory immediately.
- potential performance issues: With large data sets, there may be increased memory consumption (Out Of Memory) and application slowdown.
- ease of implementation: ScrollView is extremely easy to use and works well for short lists, forms, static screens, or when the list has a predetermined, small number of items.
- vertical or horizontal scrolling support: By default, it scrolls vertically (
vertical
), but you can easily switch to horizontal scrolling (horizontal={true}
). - support for various scrolling effects: Such as
pagingEnabled
,showsVerticalScrollIndicator
,bounces
, etc.
When to avoid ScrollView?
ScrollView is not the best choice in situations where data is dynamically fetched from the API and the number of items is not predetermined. Also, when there is a risk that the list will contain hundreds or thousands of items, using ScrollView can lead to serious performance and memory consumption problems. In cases where it is crucial for the application to maintain smooth operation and optimal management of device resources, a much better solution will be to use virtualization-based components such as FlatList or FlashList.
Code example with ScrollView list:
import { ScrollView, Text, View } from 'react-native';
const App = () => (
<ScrollView>
{[...Array(20)].map((_, index) => (
<View key={index} style={{ padding: 20, backgroundColor: '#e0e0e0', marginBottom: 10 }}>
<Text>Item {index + 1}</Text>
</View>
))}
</ScrollView>
);
In the example above, the ScrollView renders 20 items at once, providing a simple and quick way to have scrollable content.
2. FlatList
FlatList is one of the most commonly used list rendering components in React Native. It was designed to efficiently display large datasets without loading all the elements at once. Unlike ScrollView, FlatList uses a virtualization mechanism – it renders only those elements that are currently visible on the screen, and a small number of additional buffer elements. This significantly reduces memory consumption and improves the smoothness of the application.
FlatList works best when data is homogeneous and does not require special grouping. It also allows easy management of headers, footers, separators between elements and support for pull-to-refresh or infinite scroll gestures.
FlatList characteristics
FlatList automatically manages the process of creating and destroying views, ensuring that only those elements that are actually needed at a given time are in memory. Key properties, such as initialNumToRender
, maxToRenderPerBatch
or windowSize
, allow you to adjust the number of rendered elements to your specific application and expected performance.
One of the biggest advantages of FlatList is its simplicity of implementation while maintaining good performance even with large data sets. However, for extremely large lists with tens of thousands of elements, the component may exhibit some limitations in smoothness, especially on older or weaker devices. FlatList also makes it easy to create multi-column lists by setting the numColumns
property , making it a flexible tool for more than just standard vertical layouts.
It is worth remembering that for each item in the FlatList it is necessary to define a uniquekey (keyExtractor
) to ensure efficient tracking of data changes and optimization of the rendering process.
Code example:
import { FlatList, Text, View } from 'react-native';
const App = () => {
const data = [...Array(100)].map((_, i) => `Item ${i + 1}`);
return (
<FlatList
data={data}
renderItem={({ item }) => (
<View style={{ padding: 20, backgroundColor: '#f0f0f0', marginVertical: 5 }}>
<Text>{item}</Text>
</View>
)}
keyExtractor={(item, index) => index.toString()}
initialNumToRender={10}
/>
);
};
In the example above, FlatList dynamically renders only a portion of the elements, starting with the first 10, and then gradually loads more as the list is scrolled. This ensures that even with a hundred elements, the device’s memory is not overloaded and the user experiences smooth scrolling.
3. SectionList
SectionList is an advanced React Native component that extends FlatList with the ability to group data into sections. It is ideal for situations where a list of data needs to be clearly divided into categories or groups, such as an alphabetically sorted contact list, a product catalog by category, or an event schedule divided into days.
In terms of operation, SectionList is based on the same virtualization mechanism as FlatList, which means that it only renders visible elements and a small buffer off-screen. This allows for high performance even with large amounts of data, while providing a more complex list structure.
Features of the SectionList component
SectionList accepts data in a special format — as an array of objects, each representing a separate section and containing its own header and set of elements (data
). This makes it possible to assign individual headers to each data group, which significantly improves the readability and organization of content in the application.
This component supports both custom rendering of headers (renderSectionHeader
) and individual items (renderItem
). Additionally, it allows you to define separators between sections, the footer of the entire list (ListFooterComponent
), and the ability to refresh data by dragging (refreshControl
).
It is worth remembering that, as with FlatList, for optimal performance, it is necessary to correctly define keys for individual elements (keyExtractor
).
SectionList, although very functional, works best in applications where organizing data into groups is logically justified and significantly affects the user experience.
Code example:
import { SectionList, Text, View } from 'react-native';
const App = () => {
const sections = [
{ title: 'A', data: ['Apple', 'Avocado'] },
{ title: 'B', data: ['Banana', 'Blueberry', 'Blackberry'] },
{ title: 'C', data: ['Cherry', 'Coconut'] },
];
return (
<SectionList
sections={sections}
renderItem={({ item }) => (
<View style={{ padding: 15, backgroundColor: '#f9f9f9', marginVertical: 4 }}>
<Text>{item}</Text>
</View>
)}
renderSectionHeader={({ section: { title } }) => (
<View style={{ backgroundColor: '#ddd', padding: 10 }}>
<Text style={{ fontWeight: 'bold' }}>{title}</Text>
</View>
)}
keyExtractor={(item, index) => item + index}
/>
);
};
In this example, SectionList renders three sections with corresponding headers, displaying grouped data in a clear manner. This layout is particularly useful in applications where the user expects easy navigation through a larger number of categories or grouped information.
4. VirtualizedList
VirtualizedList is a low-level component in React Native that serves as the foundation for more popular components such as FlatList and SectionList. It provides full control over the list rendering mechanism, allowing the developer to manage which items are currently visible and which should be stored in memory. This solution is mainly intended for advanced scenarios where standard components do not offer sufficient flexibility.
VirtualizedList does not accept a ready-made data array like FlatList, but requires explicit specification of how to retrieve items (getItem
) and the number of items in the collection (getItemCount
). This allows for more efficient memory management and optimization of list behavior with non-standard data sources such as streams, local databases, or dynamic generators.
Features of VirtualizedList
VirtualizedList provides a very high level of control over the rendering process, making it a good choice for situations that require non-standard data structures or unusual ways of processing list content.
At the same time, using VirtualizedList comes with greater responsibility for the developer. It requires manual implementation of data handling functions and proper key management to ensure smooth operation and avoid problems with inefficient rendering.
This component supports all features typical of virtualized lists: rendering only visible items, setting the number of initial items (initialNumToRender
), controlling the rendering window (windowSize
), and support for refresh (onRefresh
) and loading more data when scrolling (onEndReached
) functions.
VirtualizedList is generally not recommended as the first choice for most projects — if your application’s needs are standard, FlatList or FlashList will be more suitable. However, in cases of very specific data structures, VirtualizedList remains an extremely powerful tool.
Code example:
import { VirtualizedList, Text, View } from 'react-native';
const App = () => {
const data = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`);
const getItem = (data, index) => data[index];
const getItemCount = (data) => data.length;
return (
<VirtualizedList
data={data}
initialNumToRender={10}
renderItem={({ item }) => (
<View style={{ padding: 20, backgroundColor: '#e0f7fa', marginVertical: 5 }}>
<Text>{item}</Text>
</View>
)}
keyExtractor={(item, index) => index.toString()}
getItem={getItem}
getItemCount={getItemCount}
/>
);
};
In the example above, VirtualizedList renders items dynamically using its own getItem
and getItemCount
functions. Although the code is a bit more complex than FlatList, it gives you complete control over how data is retrieved and processed during application runtime.
5. FlashList
FlashList is a modern list component created by Shopify, designed specifically for maximum performance and scalability in mobile applications. It addresses the limitations of traditional solutions such as FlatList, which can lose performance with very large data sets. With FlashList, it is possible to build lists containing hundreds of thousands of items without noticeable performance degradation — and with minimal configuration.
Unlike previous components, FlashList introduces mechanisms familiar from native solutions such as RecyclerView (Android) and UITableView (iOS), utilizing view recycling, precise element size estimation, and intelligent memory management. All this translates into significantly lower resource consumption and smoother scrolling.
FlashList has been designed to be as easy to use as possible. Its API is similar to FlatList, making migration of existing projects quick and painless.
FlashList features
FlashList stands out with several key features that make it one of the best tools for rendering large lists in React Native today:
First and foremost, it implements view recycling, which means that the same components are reused to render subsequent items in the list. This drastically reduces the number of views existing in memory compared to FlatList, where each item has a separate component.
Another important feature is the use of precise element size estimation. Using the estimatedItemSize
property, FlashList optimizes the list layout before actual rendering, which eliminates many costly size recalculation operations and allows for exceptional scrolling smoothness.
FlashList also provides support for features such as headers, footers, item separators, section support (using FlashList.SectionList
), pagination, and pull-to-refresh, making it a complete and ready-to-use solution for virtually any scenario.
It is worth noting that despite all its advanced features, FlashList remains extremely easy to configure. In most cases, all you need to do is provide the data, the renderItem
function, and the estimatedItemSize
value.
Why choose FlashList?
FlashList is recommended wherever the number of items is high or the data is dynamic and changes over time. It works great in e-commerce applications (product catalogs), social applications (feeds), and content management systems (CMS, CRM).
Compared to FlatList, FlashList can offer up to several times faster scrolling and up to 10 times lower memory consumption with very large lists.
FlashList is a component of the future that allows React Native applications to run at a performance level close to that of native applications.
Code example:
import { FlashList } from '@shopify/flash-list';
import { View, Text } from 'react-native';
const data = Array.from({ length: 1000 }, (_, i) => ({ id: i.toString(), title: `Item ${i + 1}` }));
const App = () => (
<FlashList
data={data}
renderItem={({ item }) => (
<View style={{ height: 70, justifyContent: 'center', alignItems: 'center', backgroundColor: '#f0f0f0', marginVertical: 4 }}>
<Text style={{ fontSize: 18 }}>{item.title}</Text>
</View>
)}
keyExtractor={(item) => item.id}
estimatedItemSize={70}
/>
);
Additional advantages of FlashList
In addition to standard features, FlashList also offers adaptive performance management. The component automatically adjusts the number of views maintained to the scrolling speed, screen resolution, and device capabilities, ensuring smooth performance without the need to manually adjust parameters such as windowSize
or maxToRenderPerBatch
, which often required additional configuration in FlatList.
FlashList also handles lists with elements of variable or irregular height very well. With the overrideItemLayout function, developers can manually specify the height of a specific element, which allows for high performance even in very dynamic content layouts.
Another key advantage is easy migration. Due to the high API compatibility with FlatList, in most cases migration boils down to changing the import and adding the estimatedItemSize
property. This makes FlashList an attractive solution for both new projects and existing applications requiring performance optimization.
What’s more, FlashList supports sections and data grouping through the FlashList.SectionList
component, allowing you to create more advanced and structured list structures without compromising performance.
Finally, FlashList provides more predictable and stable scrolling even in applications with highly dynamic data layouts. With better element size management and advanced virtualization, users can experience perfectly smooth animations without the unwanted jumps or delays that were common in older solutions.
Summary
List rendering in React Native is a topic that requires a thoughtful approach, especially when your app needs to handle large and dynamic data sets. Each of the components discussed — ScrollView, FlatList, SectionList, VirtualizedList, and FlashList — has its specific uses and limitations. ScrollView works well with a small number of items, FlatList and SectionList offer balanced performance for typical lists, and VirtualizedList provides full control where unusual solutions are needed. However, the most attention should be paid to FlashList — a next-generation component that combines simplicity with exceptional performance. With view recycling, adaptive memory management, and support for large and complex data structures, FlashList is now the best choice for apps that need to run fast, smoothly, and reliably — regardless of scale.
FAQ – Frequently asked questions about lists in React Native
1. Does FlashList work with Expo?
Yes, FlashList works in Expo-based projects, but requires the addition of the external package @shopify/flash-list
. In older versions of Expo, it may be necessary to use the “bare workflow” mode.
2. How to test the performance of lists in React Native?
List performance is best measured with tools such as Flipper, React DevTools, and Profile in Android Studio. It is worth monitoring the rendering time and memory usage when scrolling through a large number of items.
3. Does FlashList support horizontal lists?
Yes, FlashList supports horizontally scrolling lists — just set horizontal={true}
, similar to FlatList. Additionally, you can use estimatedItemSize
in width instead of height.
4. How does FlashList handle dynamically updated data?
FlashList handles data updates very well thanks to its optimized diffing process. It responds well to changes, but for best results, use stable keys (
keyExtractor
) and avoid direct data mutation.
5. Does FlashList support animations during scrolling?
Yes, FlashList works with libraries such as Reanimated and React Native Gesture Handler, which allows you to add animations to elements during scrolling, such as parallax effects or fade-ins, without significantly impacting performance.


