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