React Native Performance: Avoiding Common Pitfalls
React Native apps feel sluggish when you fight the bridge. Here's how to keep the JS thread free.
Key Insights
- FlatList with proper key extraction and getItemLayout prevents re-render storms
- useMemo and useCallback matter more in React Native than web due to bridge costs
- Animated API with useNativeDriver runs animations on the UI thread at 60fps
FlatList Optimization
<FlatList
data={items}
keyExtractor={(item) => item.id}
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
renderItem={({ item }) => <MemoizedItem item={item} />}
maxToRenderPerBatch={10}
windowSize={5}
/>
Native Driver Animations
const fadeAnim = useRef(new Animated.Value(0)).current;
Animated.timing(fadeAnim, {
toValue: 1,
duration: 300,
useNativeDriver: true, // runs on UI thread
}).start();
Avoiding Bridge Traffic
Batch state updates and minimize the data crossing the bridge. Use InteractionManager to defer heavy work until after animations complete.