Performance optimization is crucial for a smooth user experience in React Native apps. Here are the best techniques:
useMemo and useCallback to Prevent Unnecessary RendersReact components re-render when props or state change. Use useMemo and useCallback to optimize performance.
useMemo: Caches expensive calculations.useCallback: Caches function instances.import React, { useState, useMemo, useCallback } from 'react';
import { View, Text, Button } from 'react-native';
const ExpensiveComponent = ({ count }) => {
  const computedValue = useMemo(() => {
    console.log('Recalculating...');
    return count * 2;
  }, [count]);
  return <Text>Computed Value: {computedValue}</Text>;
};
const App = () => {
  const [count, setCount] = useState(0);
  const increment = useCallback(() => setCount(count + 1), [count]);
  return (
    <View>
      <ExpensiveComponent count={count} />
      <Button title="Increment" onPress={increment} />
    </View>
  );
};
export default App;
* Reduces re-renders, improving performance.
React.memo to Avoid Re-Rendering Unchanged ComponentsReact re-renders child components even if their props haven’t changed. Use React.memo to prevent this.
import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';
const MemoizedText = React.memo(({ text }) => {
  console.log('Rendering MemoizedText');
  return <Text>{text}</Text>;
});
const App = () => {
  const [count, setCount] = useState(0);
  return (
    <View>
      <MemoizedText text="This component won't re-render" />
      <Text>Count: {count}</Text>
      <Button title="Increment" onPress={() => setCount(count + 1)} />
    </View>
  );
};
export default App;
* Prevents unnecessary re-renders of static components.
When dealing with large lists, avoid using ScrollView. Instead, use FlatList, which efficiently renders only the visible items.
<ScrollView>
  {data.map(item => (
    <Text key={item.id}>{item.name}</Text>
  ))}
</ScrollView>
* ScrollView loads all items into memory at once, causing slowdowns.
<FlatList
  data={data}
  keyExtractor={item => item.id}
  renderItem={({ item }) => <Text>{item.name}</Text>}
  initialNumToRender={10} // Render only 10 items initially
  maxToRenderPerBatch={10} // Load items in batches
  windowSize={5} // Keep only 5 screens worth of items in memory
/>
* FlatList only renders visible items, improving performance.
react-native-fast-image)Large, unoptimized images can slow down your app.
react-native-fast-imageInstall it:
npm install react-native-fast-image
Usage:
import FastImage from 'react-native-fast-image';
<FastImage
  style={{ width: 200, height: 200 }}
  source={{ uri: 'https://example.com/image.jpg' }}
  resizeMode={FastImage.resizeMode.cover}
/>
InteractionManager for Heavy TasksTo avoid blocking UI updates, defer heavy tasks using InteractionManager.
import { InteractionManager } from 'react-native';
useEffect(() => {
  const task = InteractionManager.runAfterInteractions(() => {
    // Perform expensive operations here
  });
  return () => task.cancel();
}, []);
* Ensures animations and UI remain smooth.
setState CallsEvery time you update state, React re-renders the component. Minimize unnecessary state updates.
const [count, setCount] = useState(0);
const increment = () => {
  setCount(count + 1);
  setCount(count + 2);
};
* Causes multiple re-renders.
const increment = () => {
  setCount(prev => prev + 2);
};
Hermes is a lightweight JavaScript engine optimized for React Native.
Edit android/app/build.gradle:
enableHermes: true
Then rebuild the project:
cd android && ./gradlew clean
cd .. && npx react-native run-android
* Improves startup time and reduces memory usage.
react-native-reanimated)Use react-native-reanimated for smoother animations instead of Animated.
react-native-reanimatednpm install react-native-reanimated
import Animated, { Easing } from 'react-native-reanimated';
const animation = new Animated.Value(0);
Animated.timing(animation, {
  toValue: 1,
  duration: 500,
  easing: Easing.linear,
}).start();
redux-persistIf you use Redux, persist the state to avoid unnecessary API calls.
redux-persistnpm install redux-persist
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
const persistConfig = { key: 'root', storage: AsyncStorage };
const persistedReducer = persistReducer(persistConfig, rootReducer);
* Reduces redundant API calls by caching state.
useNativeDriver for AnimationsAnimations in React Native should offload work to the GPU.
Animated.timing(animatedValue, {
  toValue: 1,
  duration: 500,
  useNativeDriver: true,
}).start();
* Prevents UI thread lag.
| Optimization Tip | Benefit | 
|---|---|
| useMemo&useCallback | Prevents unnecessary re-renders | 
| React.memo | Caches components | 
| Use FlatListinstead ofScrollView | Improves list performance | 
| Use react-native-fast-image | Faster image loading | 
| Use InteractionManager | Defer heavy tasks | 
| Minimize setStatecalls | Reduces unnecessary re-renders | 
| Enable Hermes (Android) | Speeds up execution | 
| Use react-native-reanimated | Improves animation smoothness | 
| Persist Redux state | Avoids redundant API calls | 
| Use useNativeDriver | Runs animations on the GPU |