Performance Optimization
Mobile users expect fast, smooth apps. Let's learn how to identify and fix performance issues in both React Native and Flutter apps.
Performance Checklist
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Performance Optimization โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โ Optimize images (resize, compress) โ
โ โ Use lazy loading for lists โ
โ โ Minimize re-renders โ
โ โ Use memoization (useMemo, React.memo) โ
โ โ Reduce bundle size โ
โ โ Avoid memory leaks โ
โ โ Optimize animations โ
โ โ Use native modules for heavy tasks โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
React Native Performance Tips
import React, { useMemo, useCallback } from 'react';
import { FlatList } from 'react-native';
// BAD: Re-renders on every parent update
const BadListItem = ({ item }) => (
<View><Text>{item.name}</Text></View>
);
// GOOD: Memoized component
const GoodListItem = React.memo(({ item, onPress }) => (
<TouchableOpacity onPress={() => onPress(item.id)}>
<Text>{item.name}</Text>
</TouchableOpacity>
));
// GOOD: Use useCallback for functions passed as props
const OptimizedList = ({ items }) => {
const handlePress = useCallback((id) => {
console.log('Pressed:', id);
}, []);
return (
<FlatList
data={items}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) => (
<GoodListItem item={item} onPress={handlePress} />
)}
// Optimize FlatList performance
initialNumToRender={10}
maxToRenderPerBatch={10}
windowSize={5}
/>
);
};
Flutter Performance Tips
// BAD: Unnecessary rebuilds
class BadWidget extends StatefulWidget {
@override
_BadWidgetState createState() => _BadWidgetState();
}
class _BadWidgetState extends State<BadWidget> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'), // Rebuilds entire widget
ElevatedButton(
onPressed: () => setState(() => _count++),
child: Text('Increment'),
),
],
);
}
}
// GOOD: Use const constructors and split widgets
class GoodWidget extends StatelessWidget {
const GoodWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
const Text('Static content'), // Never rebuilds
CounterWidget(), // Only this rebuilds
],
);
}
}
// GOOD: Use ListView.builder for large lists
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index]));
},
)
Profiling Tools
- React Native: Flipper, React DevTools, Performance Monitor
- Flutter: DevTools, Timeline, Widget Inspector
- Both: Platform-specific profilers (Instruments, Android Profiler)