logo
React Native Practical - Interview Questions and Answers
How do you optimize performance in React Native?
How to Optimize Performance in React Native

Performance optimization is crucial for a smooth user experience in React Native apps. Here are the best techniques:


1. Use useMemo and useCallback to Prevent Unnecessary Renders

React components re-render when props or state change. Use useMemo and useCallback to optimize performance.

* Solution: Memoization
  • 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.


2. Use React.memo to Avoid Re-Rendering Unchanged Components

React 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.


3. Optimize FlatList and ScrollView

When dealing with large lists, avoid using ScrollView. Instead, use FlatList, which efficiently renders only the visible items.

* Bad (Performance Issue)
<ScrollView>
  {data.map(item => (
    <Text key={item.id}>{item.name}</Text>
  ))}
</ScrollView>

* ScrollView loads all items into memory at once, causing slowdowns.

* Good (Optimized)
<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.


4. Optimize Images (Use react-native-fast-image)

Large, unoptimized images can slow down your app.

* Solution: Use react-native-fast-image

Install 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}
/>
* Faster image loading with caching.

5. Use the InteractionManager for Heavy Tasks

To 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.


6. Reduce setState Calls

Every time you update state, React re-renders the component. Minimize unnecessary state updates.

* Bad (Inefficient)
const [count, setCount] = useState(0);

const increment = () => {
  setCount(count + 1);
  setCount(count + 2);
};

* Causes multiple re-renders.

* Good (Optimized)
const increment = () => {
  setCount(prev => prev + 2);
};
* Batch updates reduce re-renders.

7. Enable Hermes Engine (For Android Performance)

Hermes is a lightweight JavaScript engine optimized for React Native.

* Enable Hermes

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.


8. Optimize Animations (Use react-native-reanimated)

Use react-native-reanimated for smoother animations instead of Animated.

* Install react-native-reanimated
npm install react-native-reanimated
* Usage
import Animated, { Easing } from 'react-native-reanimated';

const animation = new Animated.Value(0);

Animated.timing(animation, {
  toValue: 1,
  duration: 500,
  easing: Easing.linear,
}).start();
* More efficient animations with better FPS.

9. Optimize Redux with redux-persist

If you use Redux, persist the state to avoid unnecessary API calls.

* Install redux-persist
npm install redux-persist
* Usage
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.


10. Use useNativeDriver for Animations

Animations in React Native should offload work to the GPU.

Animated.timing(animatedValue, {
  toValue: 1,
  duration: 500,
  useNativeDriver: true,
}).start();

* Prevents UI thread lag.


Final Summary
Optimization Tip Benefit
useMemo & useCallback Prevents unnecessary re-renders
React.memo Caches components
Use FlatList instead of ScrollView Improves list performance
Use react-native-fast-image Faster image loading
Use InteractionManager Defer heavy tasks
Minimize setState calls 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