Profiling
React DevTools
bash
npm install --save-dev react-devtoolsPerformance Monitor
javascript
import { Performance } from 'react-native';
// Enable in dev menu
// Shows FPS, RAM, and JS execution timeList Optimization
FlatList vs ScrollView
javascript
// Bad - ScrollView with many items
<ScrollView>
{items.map(item => (
<Item key={item.id} data={item} />
))}
</ScrollView>
// Good - FlatList with virtualization
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Item data={item} />}
/>getItemLayout
javascript
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={keyExtractor}
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
/>removeClippedSubviews
javascript
<FlatList
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={5}
/>Memoization
React.memo
javascript
const ExpensiveComponent = React.memo(({ data }) => {
return <Text>{data.value}</Text>;
});useMemo
javascript
function List({ items }) {
const sortedItems = useMemo(() => {
return items.sort((a, b) => a.id - b.id);
}, [items]);
return <FlatList data={sortedItems} />;
}useCallback
javascript
const handlePress = useCallback(() => {
console.log('Pressed');
}, []);
<TouchableOpacity onPress={handlePress}>
<Text>Press</Text>
</TouchableOpacity>Image Optimization
Resize Images
javascript
<Image
source={{ uri: 'https://example.com/image.png' }}
style={{ width: 100, height: 100 }}
resizeMode="cover"
/>Cache
javascript
<Image
source={{
uri: 'https://example.com/image.png',
cache: 'force-cache',
}}
/>Fast Image
bash
npm install react-native-fast-imagejavascript
import FastImage from 'react-native-fast-image';
<FastImage
style={{ width: 200, height: 200 }}
source={{
uri: 'https://example.com/image.png',
priority: FastImage.priority.high,
}}
resizeMode={FastImage.resizeMode.contain}
/>Bundle Size
Code Splitting
javascript
import { lazy } from 'react';
const HeavyComponent = lazy(() => import('./HeavyComponent'));Tree Shaking
javascript
// Bad
import { Button, Text, View } from 'react-native';
// Good - import only what's needed
import { View } from 'react-native';Network Optimization
Request Batching
javascript
// Bad - Multiple requests
fetch('/api/user/1');
fetch('/api/user/2');
fetch('/api/user/3');
// Good - Single batch request
fetch('/api/users?ids=1,2,3');Caching
javascript
import { ASStorage } from '@react-native-async-storage/async-storage';
async function fetchWithCache(url) {
const cached = await ASStorage.getItem(url);
if (cached) return JSON.parse(cached);
const response = await fetch(url);
const data = await response.json();
await ASStorage.setItem(url, JSON.stringify(data));
return data;
}Rendering Optimization
Avoid Inline Functions
javascript
// Bad
<FlatList
renderItem={({ item }) => (
<Button onPress={() => console.log(item.id)} />
)}
/>
// Good
const renderItem = useCallback(({ item }) => (
<Button onPress={handlePress} item={item} />
), [handlePress]);Use Key Props
javascript
// Good
{items.map(item => (
<Item key={item.id} data={item} />
))}Hermes Engine
Enable Hermes
javascript
// android/app/build.gradle
project.ext.react = [
enableHermes: true,
]Production Build
Release Mode
bash
# Android
cd android && ./gradlew assembleRelease
# iOS
Product → Scheme → Edit Scheme → Build Configuration → ReleaseBest Practices
- 1Profile first: Identify bottlenecks
- 2Measure performance: Use metrics
- 3Test on real devices: Emulators aren't accurate
- 4Optimize images: Major performance impact
- 5Use FlatList: For long lists
- 6Memoize selectively: Not everything needs it
Conclusion
Performance optimization is iterative. Profile, optimize, measure, repeat.