回答要点
React Native 性能优化概览
React Native 应用性能优化涉及多个层面,包括渲染优化、内存管理、网络优化和原生模块优化等。
1. 渲染优化
避免不必要的重渲染
javascriptimport React, { memo, useCallback, useMemo } from 'react'; // 使用 React.memo 包裹纯展示组件 const ListItem = memo(({ item, onPress }) => { return ( <TouchableOpacity onPress={onPress}> <Text>{item.title}</Text> </TouchableOpacity> ); }); function ParentComponent() { const [data, setData] = useState([]); // 使用 useCallback 缓存回调函数 const handlePress = useCallback((id) => { console.log('点击:', id); }, []); // 使用 useMemo 缓存计算结果 const sortedData = useMemo(() => { return data.sort((a, b) => b.score - a.score); }, [data]); return ( <FlatList data={sortedData} renderItem={({ item }) => ( <ListItem item={item} onPress={() => handlePress(item.id)} /> )} /> ); }
列表优化
javascript<FlatList data={largeDataSet} renderItem={renderItem} keyExtractor={item => item.id} // 性能优化属性 initialNumToRender={10} // 减少首屏渲染数量 maxToRenderPerBatch={10} // 控制每批渲染量 windowSize={5} // 可视区域外缓存的屏幕数 removeClippedSubviews={true} // 移除屏幕外视图 getItemLayout={getItemLayout} // 跳过布局计算 updateCellsBatchingPeriod={50} // 控制更新频率 />
2. 图片优化
图片加载优化
javascriptimport FastImage from 'react-native-fast-image'; // 使用 react-native-fast-image 替代原生 Image <FastImage source={{ uri: 'https://example.com/image.jpg', priority: FastImage.priority.normal, cache: FastImage.cacheControl.immutable, }} style={{ width: 200, height: 200 }} resizeMode={FastImage.resizeMode.cover} />
图片尺寸优化
- 使用适当尺寸的图片,避免加载过大图片
- 实现图片懒加载
- 使用 WebP 格式减少体积
- 压缩图片质量(建议 80% 左右)
3. 内存优化
避免内存泄漏
javascriptimport { useEffect, useRef } from 'react'; function MyComponent() { const isMounted = useRef(true); useEffect(() => { fetchData().then(data => { // 检查组件是否仍然挂载 if (isMounted.current) { setData(data); } }); return () => { isMounted.current = false; }; }, []); }
及时清理资源
javascriptuseEffect(() => { const subscription = eventEmitter.addListener('event', handler); const timer = setInterval(callback, 1000); return () => { // 清理订阅和定时器 subscription.remove(); clearInterval(timer); }; }, []);
4. JS 引擎优化
使用 Hermes 引擎
javascript// android/app/build.gradle project.ext.react = [ enableHermes: true ] // ios/Podfile use_react_native!( :hermes_enabled => true )
Hermes 优势:
- 启动时间减少 50%
- 内存占用减少 30%
- 支持字节码预编译
- 更好的崩溃报告
5. 原生模块优化
减少 Bridge 通信
javascript// ❌ 避免频繁的小数据传输 for (let i = 0; i < 100; i++) { NativeModules.MyModule.process(i); // 100 次 Bridge 调用 } // ✅ 批量传输数据 NativeModules.MyModule.processBatch(Array.from({length: 100}, (_, i) => i));
使用 TurboModules(新架构)
- 按需加载原生模块
- 减少启动时间
- 支持同步调用
6. 网络优化
请求优化
javascript// 使用缓存策略 const fetchWithCache = async (url) => { const cached = await AsyncStorage.getItem(url); if (cached) return JSON.parse(cached); const response = await fetch(url); const data = await response.json(); await AsyncStorage.setItem(url, JSON.stringify(data)); return data; }; // 请求去重 const pendingRequests = new Map(); const dedupedFetch = (url) => { if (pendingRequests.has(url)) { return pendingRequests.get(url); } const promise = fetch(url).finally(() => { pendingRequests.delete(url); }); pendingRequests.set(url, promise); return promise; };
7. 动画性能
使用原生驱动动画
javascriptimport { Animated } from 'react-native'; const fadeAnim = new Animated.Value(0); Animated.timing(fadeAnim, { toValue: 1, duration: 1000, useNativeDriver: true, // 使用原生驱动 }).start();
避免在动画中执行重操作
javascript// ❌ 避免在动画回调中执行复杂操作 Animated.timing(value, { toValue: 1, duration: 1000, }).start(() => { // 避免在这里执行耗时操作 heavyComputation(); });
8. 常见性能陷阱及解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 列表卡顿 | 渲染过多项目 | 使用 FlatList,启用虚拟化 |
| 内存泄漏 | 未清理订阅 | useEffect 返回清理函数 |
| 启动慢 | JS Bundle 过大 | 启用 Hermes,代码分割 |
| 图片加载慢 | 图片过大 | 使用 FastImage,压缩图片 |
| 重渲染频繁 | 状态更新不当 | 使用 memo, useCallback |
| 白屏时间长 | 同步任务阻塞 | 使用 InteractionManager |
9. 性能监控
javascriptimport { InteractionManager } from 'react-native'; // 延迟执行非关键任务 InteractionManager.runAfterInteractions(() => { // 在动画和交互完成后执行 loadHeavyData(); }); // 使用 Performance API const measurePerformance = () => { const start = performance.now(); // 执行操作 const end = performance.now(); console.log(`操作耗时: ${end - start}ms`); };
10. 性能优化检查清单
- 使用 FlatList 替代 ScrollView 展示长列表
- 组件使用 React.memo 优化
- 回调函数使用 useCallback 缓存
- 复杂计算使用 useMemo 缓存
- 启用 Hermes JavaScript 引擎
- 使用 FastImage 加载图片
- 动画使用 useNativeDriver
- 及时清理订阅和定时器
- 实现图片懒加载
- 使用 InteractionManager 延迟非关键任务