Профилирование производительности
Прежде чем оптимизировать, нужно найти узкие места. React Native предоставляет инструменты для профилирования.
▸React Dev Tools Profiler
▸Systrace (Android)
1npx react-native run-android --variant=release2# Затем используйте Android Studio Profiler
Виртуализация списков
▸FlatList вместо ScrollView
ScrollView рендерит все элементы одновременно. FlatList виртуализирует список, рендеря только видимые элементы.
1// ❌ Плохо2import { ScrollView } from 'react-native';3<ScrollView>4 {items.map(item => <Item key={item.id} {...item} />)}5</ScrollView>67// ✅ Хорошо8import { FlatList } from 'react-native';9<FlatList10 data={items}11 keyExtractor={(item) => item.id}12 renderItem={({ item }) => <Item {...item} />}13 initialNumToRender={10}14 maxToRenderPerBatch={10}15 windowSize={5}16/>
▸Оптимальные пропсы FlatList
initialNumToRender — количество элементов при первом рендереmaxToRenderPerBatch — максимум элементов за один батчwindowSize — количество экранов для виртуализацииgetItemLayout — фиксированная высота элементов1getItemLayout={(data, index) => ({2 length: ITEM_HEIGHT,3 offset: ITEM_HEIGHT * index,4 index,5})}
Мемоизация компонентов
▸React.memo
Оборачивает компонент и пропускает рендер если пропсы не изменились.
1const UserCard = React.memo(({ name, avatar }) => (2 <View style={styles.card}>3 <Image source={{ uri: avatar }} style={styles.avatar} />4 <Text>{name}</Text>5 </View>6));
▸useMemo для вычислений
1function FilteredList({ items, filterText }) {2 const filteredItems = useMemo(() => {3 return items.filter(item =>4 item.name.toLowerCase().includes(filterText.toLowerCase())5 );6 }, [items, filterText]);78 return (9 <FlatList10 data={filteredItems}11 renderItem={({ item }) => <Item {...item} />}12 />13 );14}
▸useCallback для функций
1const handlePress = useCallback((id) => {2 navigation.navigate('Details', { id });3}, [navigation]);
Оптимизация рендеринга
▸Избегайте анонимных функций в JSX
1// ❌ Плохо — создаёт новую функцию каждый рендер2<FlatList3 renderItem={({ item }) => <Item onPress={() => handlePress(item.id)} />}4/>56// ✅ Хорошо7const renderItem = useCallback(({ item }) => (8 <Item onPress={() => handlePress(item.id)} />9), [handlePress]);1011<FlatList renderItem={renderItem} />
▸Изображения
1import FastImage from 'react-native-fast-image';23// Используйте FastImage вместо Image4<FastImage5 source={{ uri: imageUrl, priority: FastImage.priority.normal }}6 style={{ width: 200, height: 200 }}7 resizeMode={FastImage.resizeMode.cover}8/>
Устранение утечек памяти
▸Очистка подписок
1useEffect(() => {2 const subscription = DeviceEventEmitter.addListener(3 'event', handler4 );56 return () => {7 subscription.remove(); // Обязательно отписывайтесь8 };9}, []);
▸Очистка таймеров
1useEffect(() => {2 const timer = setInterval(() => {3 // ...4 }, 1000);56 return () => clearInterval(timer);7}, []);
Заключение
Производительность React Native определяется правильным использованием FlatList, мемоизацией компонентов и профилированием. Регулярное профилирование помогает выявить узкие места до того, как они станут проблемой для пользователей.