Expo应用的性能优化是确保良好用户体验的关键。Expo基于React Native,因此许多React Native的性能优化技巧同样适用,同时Expo也提供了一些特定的优化工具和策略。
性能优化策略:
- 组件渲染优化
使用React.memo、useMemo和useCallback减少不必要的渲染:
typescript// 使用React.memo避免不必要的重新渲染 const MyComponent = React.memo(({ data }) => { return <Text>{data.value}</Text>; }); // 使用useMemo缓存计算结果 function ExpensiveComponent({ items }) { const sortedItems = useMemo(() => { return items.sort((a, b) => a.id - b.id); }, [items]); return <FlatList data={sortedItems} />; } // 使用useCallback缓存函数 function ParentComponent() { const handleClick = useCallback(() => { console.log('Clicked'); }, []); return <ChildComponent onClick={handleClick} />; }
- 列表优化
使用FlatList而不是ScrollView处理长列表:
typescript<FlatList data={items} renderItem={({ item }) => <Item item={item} />} keyExtractor={(item) => item.id} removeClippedSubviews={true} maxToRenderPerBatch={10} windowSize={10} initialNumToRender={10} getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index, })} />
关键属性说明:
removeClippedSubviews:移除屏幕外的视图maxToRenderPerBatch:每批渲染的项目数windowSize:渲染窗口大小initialNumToRender:初始渲染项目数getItemLayout:提供项目布局信息
- 图片优化
使用expo-image和图片缓存策略:
typescriptimport { Image } from 'expo-image'; <Image source={{ uri: 'https://example.com/image.jpg' }} style={{ width: 200, height: 200 }} cachePolicy="memory-disk" contentFit="cover" transition={200} />
优化技巧:
- 使用适当的图片尺寸
- 启用缓存策略
- 使用WebP格式
- 懒加载图片
- 网络请求优化
使用缓存和请求去重:
typescriptimport { useQuery } from '@tanstack/react-query'; function UserProfile({ userId }) { const { data, isLoading } = useQuery({ queryKey: ['user', userId], queryFn: () => fetchUser(userId), staleTime: 5 * 60 * 1000, // 5分钟 cacheTime: 10 * 60 * 1000, // 10分钟 }); if (isLoading) return <Loading />; return <Text>{data.name}</Text>; }
- 动画优化
使用react-native-reanimated进行高性能动画:
typescriptimport Animated, { useSharedValue, useAnimatedStyle, withTiming, } from 'react-native-reanimated'; function AnimatedBox() { const opacity = useSharedValue(0); const animatedStyle = useAnimatedStyle(() => { return { opacity: withTiming(opacity.value, { duration: 500 }), }; }); useEffect(() => { opacity.value = 1; }, []); return <Animated.View style={animatedStyle} />; }
- 内存管理
及时释放资源:
typescript// 取消网络请求 useEffect(() => { const controller = new AbortController(); fetchData(controller.signal); return () => controller.abort(); }, []); // 清理定时器 useEffect(() => { const timer = setInterval(() => { console.log('Tick'); }, 1000); return () => clearInterval(timer); }, []); // 清理订阅 useEffect(() => { const subscription = someEvent.subscribe(); return () => subscription.unsubscribe(); }, []);
- Bundle优化
减少应用包大小:
typescript// 代码分割 const LazyComponent = React.lazy(() => import('./LazyComponent')); // 动态导入 const loadModule = async () => { const module = await import('./heavyModule'); module.doSomething(); }; // 移除未使用的依赖 npm prune
- 使用Expo的性能工具
Expo提供了一些性能监控工具:
typescriptimport { Performance } from 'react-native'; // 记录性能标记 Performance.mark('component-start'); // 组件渲染完成后 Performance.mark('component-end'); // 测量性能 Performance.measure('component-render', 'component-start', 'component-end');
性能分析工具:
-
React DevTools Profiler
- 分析组件渲染性能
- 识别性能瓶颈
- 优化渲染次数
-
Flipper
- 网络请求监控
- 布局检查
- 内存分析
-
Expo DevTools
- 实时性能监控
- Bundle大小分析
- 加载时间追踪
常见性能问题及解决方案:
-
列表滚动卡顿
- 使用FlatList而不是ScrollView
- 启用
removeClippedSubviews - 提供正确的
getItemLayout
-
图片加载慢
- 使用expo-image
- 启用缓存
- 使用适当的图片尺寸
-
应用启动慢
- 优化初始化代码
- 延迟加载非关键模块
- 使用启动画面
-
内存泄漏
- 及时清理订阅和定时器
- 使用WeakMap和WeakSet
- 定期检查内存使用
最佳实践:
-
性能监控:定期使用性能工具分析应用
-
渐进优化:先优化关键路径,再优化次要功能
-
测试覆盖:在不同设备上测试性能
-
持续优化:将性能优化作为持续过程
-
用户体验:平衡性能和功能,优先保证核心体验
通过系统性的性能优化,可以显著提升Expo应用的用户体验和竞争力。