2024年02月15日3 分钟

React 性能优化实战技巧

10 个实用的 React 性能优化技巧,涵盖渲染优化、状态管理和代码分割

为什么性能优化很重要

性能直接影响用户体验。一个卡顿的页面会导致用户流失,而流畅的交互则能提升用户满意度和转化率。

1. 使用 React.memo 避免不必要的重渲染

const ExpensiveComponent = React.memo(({ data }: { data: string[] }) => {
  return (
    <ul>
      {data.map(item => <li key={item}>{item}</li>)}
    </ul>
  )
})

React.memo 会对 props 进行浅比较,只有 props 变化时才会重新渲染。

2. 善用 useMemo 和 useCallback

function SearchList({ items, query }: Props) {
  // 只在 items 或 query 变化时重新计算
  const filtered = useMemo(
    () => items.filter(item => item.includes(query)),
    [items, query]
  )

  // 稳定的回调引用
  const handleClick = useCallback((id: string) => {
    console.log('clicked', id)
  }, [])

  return <List items={filtered} onItemClick={handleClick} />
}

3. 虚拟列表处理大数据

当列表项超过数百条时,应该使用虚拟列表只渲染可见区域的元素:

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

function VirtualList({ items }: { items: string[] }) {
  const parentRef = useRef<HTMLDivElement>(null)

  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`, position: 'relative' }}>
        {virtualizer.getVirtualItems().map(virtualItem => (
          <div key={virtualItem.key} style={{
            position: 'absolute',
            top: 0,
            transform: `translateY(${virtualItem.start}px)`,
          }}>
            {items[virtualItem.index]}
          </div>
        ))}
      </div>
    </div>
  )
}

4. 代码分割与懒加载

import dynamic from 'next/dynamic'

// 组件级别的代码分割
const HeavyChart = dynamic(() => import('./HeavyChart'), {
  loading: () => <Skeleton />,
  ssr: false,
})

5. 优化状态管理

避免状态提升过高

把状态放在尽可能靠近使用它的组件中,避免不必要的父组件重渲染。

使用 Context 的注意事项

  • 将频繁变化的值和稳定的值分开到不同的 Context
  • 考虑使用 Zustand 或 Jotai 替代复杂的 Context 嵌套

6. 图片优化

使用 Next.js Image 组件自动处理图片优化:

import Image from 'next/image'

<Image
  src="/photo.jpg"
  alt="描述"
  width={800}
  height={600}
  placeholder="blur"
  loading="lazy"
/>

总结

性能优化是一个持续的过程,最重要的是先用工具 (React DevTools Profiler、Lighthouse) 找到瓶颈,再针对性地优化。不要过度优化。

过早的优化是万恶之源 —— Donald Knuth