DEV Community

Mr Solomon 🄷
Mr Solomon 🄷

Posted on

Common React Native Performance Gotchas I Fixed in 2025 (and How to Avoid Them)

Hey DEV community šŸ‘‹
I'm a React Native dev who's been shipping mobile apps for a couple of years now. In 2025 I hit a bunch of performance walls that cost me days of debugging — so I want to share the most common ones I see (and fixed) so maybe you can skip the pain.

  1. Unnecessary re-renders from anonymous functions in render
    Classic mistake:

    data={items}
    renderItem={({ item }) => (
    doSomething(item)}>
    {item.name}

    )}
    />
    Every render creates a new function → children re-render unnecessarily.
    Fix — use useCallback:const handlePress = useCallback((item) => doSomething(item), []);

  2. Large lists without keyExtractor or getItemLayout
    FlatList without keyExtractor or getItemLayout can lag badly on long lists.
    Quick wins:
    Always add keyExtractor={(item) => item.id.toString()}
    If items have fixed height → add getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index })}

  3. Overusing useState in deeply nested components
    Lifting state too high or creating tons of tiny useState hooks kills performance.
    Better — use Zustand or Jotai for global/cross-component state instead of prop drilling + local state everywhere.

  4. Image loading without caching or placeholder
    Remote images without cache policy or blurhash placeholders cause jank.
    Use expo-image instead of — it handles caching, placeholders, and priority better out of the box.
    import { Image } from 'expo-image';

source={{ uri: imageUrl }}
placeholder={require('./blurhash-placeholder.png')}
cachePolicy="memory-disk"
style={{ width: 200, height: 200 }}
/>

  1. Not using Reanimated for animations Animated API is slow on JS thread. Switch to Reanimated 2/3 for 60fps spring/physics animations that run on UI thread. import Animated, { useSharedValue, withSpring } from 'react-native-reanimated';

const scale = useSharedValue(1);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ scale: withSpring(scale.value) }],
}));

Quick checklist I run before every release:
Profile with Flipper or React DevTools
Check re-renders with why-did-you-render
Test on low-end device (Android Go or old iPhone)
Use expo-optimize or bundle visualizer for JS size
What are your biggest RN perf wins or pains in 2025? Drop them below — let's help each other ship faster. šŸš€

ReactNative #Performance #MobileDev #Expo #JavaScript

Top comments (0)