React 性能优化实战


⚡ React 性能优化实战

📊 性能问题的常见原因

  1. 不必要的重渲染
  2. 大组件加载慢
  3. 重复计算
  4. 内存泄漏

🎯 优化策略

1. 使用 React.memo

// 优化前 - 每次父组件渲染都会重新渲染
function Child({ data }) {
  return <div>{data.title}</div>;
}

// 优化后 - 只有 props 变化时才重新渲染
const Child = React.memo(function Child({ data }) {
  return <div>{data.title}</div>;
});

2. 使用 useCallback

// 优化前 - 每次渲染都会创建新的函数
function Parent() {
  const handleClick = () => {
    console.log('Clicked!');
  };
  
  return <Child onClick={handleClick} />;
}

// 优化后 - 缓存函数,避免不必要的重新创建
function Parent() {
  const handleClick = useCallback(() => {
    console.log('Clicked!');
  }, []); // 依赖数组为空,函数永远不变
  
  return <Child onClick={handleClick} />;
}

3. 使用 useMemo

function ExpensiveComponent({ data }) {
  // 优化前 - 每次渲染都重新计算
  const processedData = data.filter(d => d.active).map(d => d.value);
  
  // 优化后 - 只有 data 变化时才重新计算
  const processedData = useMemo(() => {
    return data.filter(d => d.active).map(d => d.value);
  }, [data]);
  
  return <List data={processedData} />;
}

4. 代码分割

import { lazy, Suspense } from 'react';

// 动态导入,不在首屏加载
const HeavyComponent = lazy(() => import('./HeavyComponent'));

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

5. 虚拟列表

import { useVirtualizer } from '@tanstack/react-virtual';

function VirtualList({ items }) {
  const parentRef = useRef();
  
  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 50,
  });
  
  return (
    <div ref={parentRef} style={{ height: '400px', overflow: 'auto' }}>
      <div style={{ height: `${virtualizer.getTotalSize()}px` }}>
        {virtualizer.getVirtualItems().map((virtualItem) => (
          <div
            key={virtualItem.key}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              height: `${virtualItem.size}px`,
              transform: `translateY(${virtualItem.start}px)`,
            }}
          >
            {items[virtualItem.index]}
          </div>
        ))}
      </div>
    </div>
  );
}

📈 性能监控

使用 React DevTools Profiler 分析性能:

import { Profiler, onRenderCallback } from 'react';

function App() {
  return (
    <Profiler id="App" onRender={onRenderCallback}>
      <MainContent />
    </Profiler>
  );
}

🚀 性能检查清单

  • 使用 Chrome DevTools Performance 面板分析
  • 开启 React DevTools Profiler
  • 检查不必要的重渲染
  • 优化大列表渲染
  • 压缩代码体积
  • 使用 CDN
  • 开启 gzip/brotli 压缩
  • 配置适当的缓存策略

🎯 实战案例

案例:列表搜索优化

function SearchList({ items }) {
  const [query, setQuery] = useState('');
  
  // 优化搜索性能
  const filteredItems = useMemo(() => {
    if (!query) return items;
    return items.filter(item => 
      item.name.toLowerCase().includes(query.toLowerCase())
    );
  }, [items, query]);
  
  return (
    <div>
      <input
        value={query}
        onChange={(e) => setQuery(e.target.value)}
      />
      <List items={filteredItems} />
    </div>
  );
}

📚 总结

性能优化是一个持续的过程:

  1. 先测量,再优化 - 不要过早优化
  2. 关注用户体验 - 首屏加载和交互响应
  3. 持续监控 - 使用工具追踪性能指标
  4. 权衡取舍 - 有时为了可读性可以牺牲一点性能

你有其他 React 性能优化的技巧吗?欢迎分享!