Skip to content

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'] });

面试要点

  1. 列表优化:FlashList vs FlatList
  2. 动画方案:Reanimated UI 线程动画
  3. 启动优化:Hermes、Bundle 拆分、延迟加载
  4. 内存管理:清理订阅、避免闭包泄漏

前端面试知识库