mediumReact Native#17

FlatList performance optimization

Prompt

Optimize a FlatList rendering 1000 items. Use getItemLayout for fixed-height items, windowSize to reduce render window, and keyExtractor for stable identity.

Solution

const ITEM_HEIGHT = 50
return (
  <FlatList
    data={DATA}
    keyExtractor={item => String(item.id)}
    getItemLayout={(_, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index })}
    windowSize={5}
    removeClippedSubviews={true}
    renderItem={({ item }) => <View style={{ height: ITEM_HEIGHT, padding: 16 }}><Text>{item.text}</Text></View>}
  />
)
Mentor's take

Each prop here attacks a different cost, and being precise about which is the seniority test.

getItemLayout removes measurement, not rendering. Without it, FlatList must render rows to learn where row N sits, which is why scrollToIndex throws without it and fast scrolls show blanks. With fixed heights, offset = height × index turns positioning into O(1) arithmetic — instant jumps, accurate scrollbars. It renders nothing faster; it deletes the layout dependency.

keyExtractor is the identity contract that makes windowing safe: stable keys let React reuse row instances as the window slides. Index-as-key breaks on insert or reorder — every downstream key shifts and row state attaches to the wrong data.

windowSize={5} shrinks the mounted region from the default 21 viewport-heights to 5 — less memory and batch work, traded against blank areas on fast flings. It's a dial, not a virtue: tune it against observed blanks. removeClippedSubviews detaches off-screen native views on top of JS-side virtualization.

Unstated but implied: renderItem rows should be memoized components with stable handler props, or every window shift re-renders rows for nothing. At the point rows get complex, FlashList's recycling model is the next conversation.

Red flag: "getItemLayout makes rendering faster." It removes measurement as a dependency for positioning — precision about what it skips is what interviewers grade.

Say it: "getItemLayout turns positioning into arithmetic, keyExtractor gives the sliding window stable identity, and windowSize trades memory against blank cells — three different costs, three different knobs."