Introduction
A slow app frustrates users. React Native powers Instagram, Facebook, and others - but requires optimization. This guide covers making your React Native app fast and smooth.
Performance Pillars
┌─────────────────────────────────────────────────────────────┐
│ React Native Performance │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. JS Thread │
│ • Runs your JavaScript │
│ • UI updates, business logic │
│ • Blocked = janky UI │
│ │
│ 2. UI Thread (Main) │
│ • Native rendering │
│ • Layout calculations │
│ • Animations │
│ │
│ 3. Memory │
│ • Excessive re-renders │
│ • Large data in memory │
│ • Memory leaks │
│ │
└─────────────────────────────────────────────────────────────┘
Enable Hermes
// app.json
{
"expo": {
"jsEngine": "hermes"
}
}
// Check Hermes is enabled
import { HermesEngine } from 'react-native';
console.log(HermesEngine.isEnabled()); // true
List Optimization
FlatList Best Practices
// ❌ Bad - No optimization
<FlatList
data={items}
renderItem={({ item }) => <ItemComponent item={item} />}
/>
// ✅ Good - Optimized
<FlatList
data={items}
renderItem={({ item }) => <ItemComponent item={item} />}
keyExtractor={item => item.id}
getItemLayout={(_, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={10}
initialNumToRender={10}
ListHeaderComponent={Header}
ListFooterComponent={Footer}
/>
Virtualization
// Use FlashList for even better performance
import { FlashList } from '@shopify/flash-list';
<FlashList
data={items}
renderItem={({ item }) => <ItemComponent item={item} />}
estimatedItemSize={100}
/>
Memoization
// Prevent unnecessary re-renders
import { memo, useCallback, useMemo } from 'react';
// Memoize components
const Item = memo(({ title, onPress }) => (
<TouchableOpacity onPress={onPress}>
<Text>{title}</Text>
</TouchableOpacity>
));
// Memoize callbacks
const handlePress = useCallback((id: string) => {
navigation.navigate('Detail', { id });
}, [navigation]);
// Memoize expensive computations
const processedData = useMemo(() => {
return data.map(item => transform(item));
}, [data]);
Image Optimization
import { Image } from 'react-native';
import { FastImage } from 'react-native-fast-image';
// Use FastImage for caching
<FastImage
source={{ uri: 'https://example.com/image.jpg' }}
style={{ width: 100, height: 100 }}
resizeMode={FastImage.resizeMode.cover}
/>
// Or use expo-image
import { Image } from 'expo-image';
<Image
source="https://example.com/image.jpg"
style={{ width: 100, height: 100 }}
contentFit="cover"
cachePolicy="memory-disk"
/>
Performance Monitoring
import { PerformanceMonitor } from 'expo-performance';
// Measure execution time
const { start, end } = await PerformanceMonitor.startMeasure('my-task');
await doExpensiveTask();
end();
// Check frame rate
import { useFrameRate } from 'expo-performance';
function MyComponent() {
const frameRate = useFrameRate();
return <Text>FPS: {frameRate}</Text>;
}
Key Takeaways
- Hermes - Enable for better performance
- FlatList - Configure virtualization
- Memoization - Prevent re-renders
- Images - Use cached images
- Monitor - Measure performance
External Resources
Resources
- React Native Documentation
- Flutter Documentation
- iOS Human Interface Guidelines
- Android Developer Guide
Comments