React Native · Mobile UI at native speed
How do you make a long list perform well?
Short answer
Virtualise with FlatList or FlashList, provide stable keys, memoise row components, avoid inline handlers, and tune batch size, window size and item layout. Measure on a low-end device before and after.
List performance is usually a combination of render cost per row and the amount of layout work the list does. A FlatList only renders a window of items, but it still re-renders rows when props change and must estimate layout for items it has not measured.
import { memo } from "react";
import { FlatList, Text, View } from "react-native";
type Row = { id: string; title: string };
const RowItem = memo(function RowItem({ title }: { title: string }) {
return (
<View style={{ padding: 12 }}>
<Text>{title}</Text>
</View>
);
});
export function Feed({ rows }: { rows: Row[] }) {
return (
<FlatList
data={rows}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <RowItem title={item.title} />}
getItemLayout={(_, index) => ({ length: 56, offset: 56 * index, index })}
initialNumToRender={10}
maxToRenderPerBatch={10}
windowSize={7}
removeClippedSubviews
/>
);
}The main levers
- Stable keys from server IDs, never array index for reorderable data
- Memoised row components with primitive props
- A single stable renderItem function, not a new closure per render
- getItemLayout when rows have a known fixed height
- Tuned windowSize, initialNumToRender and maxToRenderPerBatch
- FlashList or a native list when the dataset is very large or highly dynamic
Images inside rows are a common hidden cost. Downscale assets to the rendered size, use a caching image component, and avoid decoding full-resolution photos for thumbnails. Also avoid heavy work in renderItem, such as formatting dates or filtering arrays; precompute it once.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1When would you use FlashList instead of FlatList?
- 2Why is an inline renderItem closure a problem?
- 3What does getItemLayout actually save?
- 4How do you profile a janky list?
Say it in the interview
I start by making each row cheap: stable keys, a memoised row component, primitive props and no heavy formatting in render. Then I tune the virtualisation window and add getItemLayout for fixed-height rows, or move to FlashList when the list is very large. I verify with profiling on a low-end Android device, because list jank rarely shows up on a fast simulator.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live React Native mock interview and get scored feedback on depth, clarity and confidence.