常见组件性能优化手段
- 减少不必要的渲染:
- 对于类组件,可通过
shouldComponentUpdate
生命周期方法,根据新旧 props
和 state
判断是否需要重新渲染。例如,只在 props
中某个关键值变化时才渲染。
- 对于函数组件,使用
React.memo
包裹组件,它会对 props
进行浅比较,若 props
未改变则阻止组件重新渲染。
- 优化渲染频率:
- 批量更新:React 会自动批量更新状态,但在某些异步操作或原生 DOM 事件处理中,可能不会自动批量。此时可使用
unstable_batchedUpdates
(React 18 之前)或原生的 flushSync
来手动批量更新,减少不必要的多次渲染。
- 虚拟 DOM 差异算法优化:React 使用虚拟 DOM 来计算实际 DOM 的最小变化,开发者应尽量保持组件结构稳定,减少虚拟 DOM 树的深度变化,以提高差异算法的效率。
React.memo、useMemo 和 useCallback 的适用场景
- React.memo:
- 适用场景:用于函数式组件,当组件的渲染完全取决于
props
,且 props
变化频率较低时使用。例如展示静态数据的组件,只要 props
不变就无需重新渲染。像一个展示用户基本信息的卡片组件,只要用户信息 props
不更新,就没必要重新渲染。
- useMemo:
- 适用场景:用于缓存计算结果。当一个函数的计算开销较大,且依赖项(第二个参数数组中的值)变化频率较低时使用。比如计算一个大数据列表的总和,只有当列表数据或计算规则变化时才重新计算。示例:
const sum = useMemo(() => {
let total = 0;
for (let i = 0; i < largeDataList.length; i++) {
total += largeDataList[i];
}
return total;
}, [largeDataList]);
- useCallback:
- 适用场景:用于缓存函数引用。当把一个函数作为
props
传递给子组件,且希望子组件在该函数引用不变时不重新渲染,同时该函数依赖的变量变化频率较低时使用。例如一个父组件传递一个点击处理函数给子组件按钮,只有在父组件中依赖的某些状态变化时才更新这个函数引用,防止子组件因函数引用变化而不必要的重新渲染。示例:
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);