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.

Liked this? There's more.

Every week: one practical technique, explained simply, with code you can use immediately.