ReactNative性能优化Skill react-native-performance

这个技能专注于优化React Native移动应用的性能,通过FlatList优化、组件记忆化、图像优化、包大小减少和性能分析等技术,提升应用运行效率和用户体验。关键词:React Native,性能优化,FlatList,记忆化,图像优化,包大小,性能分析,移动开发。

移动开发 0 次安装 0 次浏览 更新于 3/25/2026

name: react-native-performance user-invocable: false description: 在优化React Native应用性能时使用。涵盖FlatList优化、记忆化、图像优化、包大小减少和分析技术。 allowed-tools:

  • Read
  • Write
  • Edit
  • Bash
  • Grep
  • Glob

React Native 性能优化

在优化React Native应用以获得更好性能、更快加载时间和更流畅用户体验时使用此技能。

关键概念

列表性能

针对大数据集优化FlatList:

import React, { useCallback } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';

interface Item {
  id: string;
  title: string;
}

const ItemComponent = React.memo(({ item }: { item: Item }) => (
  <View style={styles.item}>
    <Text>{item.title}</Text>
  </View>
));

function OptimizedList({ data }: { data: Item[] }) {
  const renderItem = useCallback(
    ({ item }: { item: Item }) => <ItemComponent item={item} />,
    []
  );

  const keyExtractor = useCallback((item: Item) => item.id, []);

  const getItemLayout = useCallback(
    (data: any, index: number) => ({
      length: 80, // 固定项高度
      offset: 80 * index,
      index,
    }),
    []
  );

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      getItemLayout={getItemLayout}
      // 性能优化
      removeClippedSubviews={true}
      maxToRenderPerBatch={10}
      updateCellsBatchingPeriod={50}
      initialNumToRender={10}
      windowSize={5}
    />
  );
}

const styles = StyleSheet.create({
  item: {
    height: 80,
    padding: 16,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
});

组件记忆化

使用React.memo和useMemo:

import React, { useMemo } from 'react';
import { View, Text } from 'react-native';

interface UserCardProps {
  user: {
    id: string;
    name: string;
    email: string;
  };
  onPress: () => void;
}

// 记忆化组件以预防不必要的重新渲染
const UserCard = React.memo(({ user, onPress }: UserCardProps) => {
  return (
    <View>
      <Text>{user.name}</Text>
      <Text>{user.email}</Text>
    </View>
  );
});

// 记忆化昂贵计算
function UserList({ users }: { users: User[] }) {
  const sortedUsers = useMemo(() => {
    return [...users].sort((a, b) => a.name.localeCompare(b.name));
  }, [users]);

  return (
    <View>
      {sortedUsers.map(user => (
        <UserCard key={user.id} user={user} onPress={() => {}} />
      ))}
    </View>
  );
}

图像优化

优化图像加载和缓存:

import React from 'react';
import { Image, View } from 'react-native';
import FastImage from 'react-native-fast-image';

// 使用FastImage以获得更好性能
function OptimizedImage({ uri }: { uri: string }) {
  return (
    <FastImage
      style={{ width: 200, height: 200 }}
      source={{
        uri,
        priority: FastImage.priority.normal,
        cache: FastImage.cacheControl.immutable,
      }}
      resizeMode={FastImage.resizeMode.cover}
    />
  );
}

// 懒加载图像
function LazyImage({ uri }: { uri: string }) {
  return (
    <Image
      source={{ uri }}
      style={{ width: 200, height: 200 }}
      resizeMode="cover"
      loadingIndicatorSource={require('./placeholder.png')}
    />
  );
}

最佳实践

为事件处理器使用useCallback

预防不必要的重新渲染:

import React, { useCallback, useState } from 'react';
import { View, Button, Text } from 'react-native';

function Counter() {
  const [count, setCount] = useState(0);

  // 坏 - 每次渲染都创建新函数
  // const increment = () => setCount(count + 1);

  // 好 - 记忆化回调
  const increment = useCallback(() => {
    setCount(c => c + 1);
  }, []);

  return (
    <View>
      <Text>{count}</Text>
      <Button title="增加" onPress={increment} />
    </View>
  );
}

仅使用虚拟化列表

对可滚动内容使用FlatList/SectionList:

// 坏 - 带map的ScrollView(渲染所有项)
<ScrollView>
  {items.map(item => (
    <ItemComponent key={item.id} item={item} />
  ))}
</ScrollView>

// 好 - FlatList(虚拟化项)
<FlatList
  data={items}
  keyExtractor={item => item.id}
  renderItem={({ item }) => <ItemComponent item={item} />}
/>

避免在渲染中使用匿名函数

// 坏 - 每次渲染都创建新函数
<FlatList
  data={items}
  renderItem={({ item }) => (
    <TouchableOpacity onPress={() => console.log(item.id)}>
      <Text>{item.title}</Text>
    </TouchableOpacity>
  )}
/>

// 好 - 记忆化渲染函数
const renderItem = useCallback(({ item }: { item: Item }) => (
  <ItemRow item={item} onPress={handleItemPress} />
), [handleItemPress]);

<FlatList
  data={items}
  renderItem={renderItem}
/>

优化包大小

减少JavaScript包大小:

# 分析包
npx react-native-bundle-visualizer

# 启用Hermes引擎(用于Expo的app.json)
{
  "expo": {
    "jsEngine": "hermes"
  }
}

# 启用Hermes(用于裸React Native的android/app/build.gradle)
project.ext.react = [
  enableHermes: true
]

# 为Android使用ProGuard(android/app/build.gradle)
def enableProguardInReleaseBuilds = true

代码拆分

为更快初始加载拆分代码:

import React, { lazy, Suspense } from 'react';
import { View, ActivityIndicator } from 'react-native';

// 懒加载重型组件
const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<ActivityIndicator />}>
      <HeavyComponent />
    </Suspense>
  );
}

常见模式

防抖搜索

import React, { useState, useCallback, useEffect } from 'react';
import { TextInput, FlatList } from 'react-native';

function SearchableList({ data }: { data: Item[] }) {
  const [query, setQuery] = useState('');
  const [debouncedQuery, setDebouncedQuery] = useState('');

  // 防抖搜索
  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedQuery(query);
    }, 300);

    return () => clearTimeout(timer);
  }, [query]);

  const filteredData = useMemo(() => {
    if (!debouncedQuery) return data;
    return data.filter(item =>
      item.title.toLowerCase().includes(debouncedQuery.toLowerCase())
    );
  }, [data, debouncedQuery]);

  return (
    <>
      <TextInput
        value={query}
        onChangeText={setQuery}
        placeholder="搜索..."
      />
      <FlatList
        data={filteredData}
        keyExtractor={item => item.id}
        renderItem={({ item }) => <ItemComponent item={item} />}
      />
    </>
  );
}

优化动画

使用react-native-reanimated实现平滑动画:

import React from 'react';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';
import { Pressable } from 'react-native';

function AnimatedButton() {
  const scale = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: scale.value }],
  }));

  const handlePressIn = () => {
    scale.value = withSpring(0.95);
  };

  const handlePressOut = () => {
    scale.value = withSpring(1);
  };

  return (
    <Pressable onPressIn={handlePressIn} onPressOut={handlePressOut}>
      <Animated.View style={[styles.button, animatedStyle]}>
        <Text>按我</Text>
      </Animated.View>
    </Pressable>
  );
}

分页

实现高效分页:

import React, { useState, useCallback } from 'react';
import { FlatList, ActivityIndicator } from 'react-native';

function PaginatedList() {
  const [data, setData] = useState<Item[]>([]);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(1);

  const loadMore = useCallback(async () => {
    if (loading) return;

    setLoading(true);
    const newData = await fetchData(page);
    setData(prev => [...prev, ...newData]);
    setPage(p => p + 1);
    setLoading(false);
  }, [loading, page]);

  const renderItem = useCallback(
    ({ item }: { item: Item }) => <ItemComponent item={item} />,
    []
  );

  const renderFooter = () => {
    if (!loading) return null;
    return <ActivityIndicator style={{ margin: 16 }} />;
  };

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      onEndReached={loadMore}
      onEndReachedThreshold={0.5}
      ListFooterComponent={renderFooter}
    />
  );
}

记忆化选择器

import React, { useMemo } from 'react';
import { View, Text } from 'react-native';

interface User {
  id: string;
  name: string;
  age: number;
  active: boolean;
}

function UserStats({ users }: { users: User[] }) {
  const stats = useMemo(() => {
    return {
      total: users.length,
      active: users.filter(u => u.active).length,
      averageAge: users.reduce((sum, u) => sum + u.age, 0) / users.length,
    };
  }, [users]);

  return (
    <View>
      <Text>总数: {stats.total}</Text>
      <Text>活跃: {stats.active}</Text>
      <Text>平均年龄: {stats.averageAge.toFixed(1)}</Text>
    </View>
  );
}

图像预加载

import { Image } from 'react-native';

async function preloadImages(imageUrls: string[]) {
  const promises = imageUrls.map(url =>
    Image.prefetch(url)
  );

  await Promise.all(promises);
}

// 用法
useEffect(() => {
  preloadImages([
    'https://example.com/image1.jpg',
    'https://example.com/image2.jpg',
  ]);
}, []);

反模式

不要在生产中使用console.log

// 坏 - 日志减慢生产
console.log('用户数据:', user);

// 好 - 删除或使用__DEV__
if (__DEV__) {
  console.log('用户数据:', user);
}

不要内联大型对象

// 坏 - 每次渲染都创建新对象
<Component
  style={{ width: 100, height: 100, backgroundColor: '#fff' }}
  config={{ option1: true, option2: false }}
/>

// 好 - 使用StyleSheet和常量
const styles = StyleSheet.create({
  component: { width: 100, height: 100, backgroundColor: '#fff' },
});

const config = { option1: true, option2: false };

<Component style={styles.component} config={config} />

别忘了清理

// 坏 - 内存泄漏
useEffect(() => {
  const timer = setInterval(() => {
    console.log('滴答');
  }, 1000);
}, []);

// 好 - 清理
useEffect(() => {
  const timer = setInterval(() => {
    console.log('滴答');
  }, 1000);

  return () => clearInterval(timer);
}, []);

不要在循环中使用setState

// 坏 - 多个重新渲染
items.forEach(item => {
  setData(prev => [...prev, item]);
});

// 好 - 单次更新
setData(prev => [...prev, ...items]);

分析工具

React DevTools分析器

import { Profiler } from 'react';

function onRenderCallback(
  id: string,
  phase: 'mount' | 'update',
  actualDuration: number
) {
  console.log(`${id} (${phase}) 耗时 ${actualDuration}ms`);
}

<Profiler id="MyComponent" onRender={onRenderCallback}>
  <MyComponent />
</Profiler>

性能监视器

import { PerformanceObserver, performance } from 'perf_hooks';

// 启用性能监视器
if (__DEV__) {
  const observer = new PerformanceObserver((list) => {
    list.getEntries().forEach((entry) => {
      console.log(`${entry.name}: ${entry.duration}ms`);
    });
  });

  observer.observe({ entryTypes: ['measure'] });
}

相关技能

  • react-native-components: 构建高性能组件
  • react-native-navigation: 优化导航性能
  • react-native-native-modules: 原生性能优化