React Native 性能优化
渲染优化
列表性能
tsx
import { FlashList } from '@shopify/flash-list';
// ❌ 避免:FlatList 大数据量性能差
<FlatList data={largeData} renderItem={renderItem} />
// ✅ 推荐:FlashList 高性能列表
<FlashList
data={largeData}
renderItem={renderItem}
estimatedItemSize={80}
// 关键:提供准确的预估高度
/>避免不必要的重渲染
tsx
import { memo, useCallback, useMemo } from 'react';
// 1. 组件 memo 化
const ListItem = memo(({ item, onPress }) => {
return (
<TouchableOpacity onPress={() => onPress(item.id)}>
<Text>{item.title}</Text>
</TouchableOpacity>
);
});
// 2. 回调函数 useCallback
function ParentComponent() {
const handlePress = useCallback((id: string) => {
// 处理点击
}, []);
return <ListItem item={item} onPress={handlePress} />;
}
// 3. 复杂计算 useMemo
const sortedData = useMemo(() => {
return data.sort((a, b) => b.date - a.date);
}, [data]);图片优化
tsx
import FastImage from 'react-native-fast-image';
// ❌ 避免:Image 没有缓存
<Image source={{ uri: imageUrl }} />
// ✅ 推荐:FastImage 自动缓存
<FastImage
source={{
uri: imageUrl,
priority: FastImage.priority.normal,
cache: FastImage.cacheControl.immutable,
}}
resizeMode={FastImage.resizeMode.cover}
/>动画性能
Reanimated 3.x
tsx
import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
runOnJS,
} from 'react-native-reanimated';
function AnimatedBox() {
const offset = useSharedValue(0);
// 在 UI 线程执行动画
const animatedStyles = useAnimatedStyle(() => ({
transform: [{ translateX: offset.value }],
}));
const handlePress = () => {
// 弹簧动画
offset.value = withSpring(offset.value + 50);
};
return (
<Animated.View style={[styles.box, animatedStyles]}>
<TouchableOpacity onPress={handlePress} />
</Animated.View>
);
}手势动画
tsx
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
function DraggableBox() {
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const gesture = Gesture.Pan()
.onUpdate((event) => {
translateX.value = event.translationX;
translateY.value = event.translationY;
})
.onEnd(() => {
translateX.value = withSpring(0);
translateY.value = withSpring(0);
});
const animatedStyle = useAnimatedStyle(() => ({
transform: [
{ translateX: translateX.value },
{ translateY: translateY.value },
],
}));
return (
<GestureDetector gesture={gesture}>
<Animated.View style={[styles.box, animatedStyle]} />
</GestureDetector>
);
}启动优化
减少 JS Bundle 体积
javascript
// metro.config.js
module.exports = {
transformer: {
minifierConfig: {
keep_fnames: true,
mangle: { toplevel: true },
compress: {
drop_console: true, // 移除 console
},
},
},
};Hermes 引擎
javascript
// android/app/build.gradle
project.ext.react = [
enableHermes: true, // 启用 Hermes
]Hermes 优势:
- 预编译字节码,启动更快
- 内存占用更低
- 更好的 GC 策略
延迟加载
tsx
import { lazy, Suspense } from 'react';
// 延迟加载大型组件
const HeavyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<LoadingSpinner />}>
<HeavyComponent />
</Suspense>
);
}内存管理
检测内存泄漏
tsx
useEffect(() => {
const subscription = eventEmitter.subscribe(handler);
// ✅ 清理订阅
return () => subscription.unsubscribe();
}, []);
useEffect(() => {
let isMounted = true;
fetchData().then(data => {
// ✅ 避免组件卸载后更新状态
if (isMounted) {
setData(data);
}
});
return () => { isMounted = false; };
}, []);性能监控
tsx
import { PerformanceObserver } from 'react-native-performance';
// 监控渲染性能
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log(`${entry.name}: ${entry.duration}ms`);
});
});
observer.observe({ entryTypes: ['measure'] });面试要点
- 列表优化:FlashList vs FlatList
- 动画方案:Reanimated UI 线程动画
- 启动优化:Hermes、Bundle 拆分、延迟加载
- 内存管理:清理订阅、避免闭包泄漏