react 性能优化的方案

React 的性能优化有非常多成熟的方案

一、组件层级的性能优化

1. 使用 React.memo(函数组件)

避免父组件渲染时导致子组件无意义渲染。

const Child = React.memo(function Child(props) {
  return <div>{props.value}</div>;
});

适用:

  • props 不变时避免重复渲染

  • PureComponent 的函数组件版

2. 使用 shouldComponentUpdate(类组件)

优化类组件:

shouldComponentUpdate(nextProps, nextState) {
  return nextProps.value !== this.props.value;
}
3. 使用 useCallback / useMemo 缓存函数和变量

避免每次 render 都创建新对象或新函数:

const handleClick = useCallback(() => {
  doSomething();
}, []);

const expensiveValue = useMemo(() => heavyCompute(data), [data]);
4. 避免在 render 中创建对象 / 函数 / 数组

不推荐:

<Component style={{ color: 'red' }} />

推荐:

const style = { color: 'red' };
<Component style={style} />

二、渲染相关的优化

5. 合理分割组件(粒度越细越能减少渲染)

减少无关组件刷新,如:

  • 表格中每一行都是一个组件

  • 表单中的每个字段独立组件

6. 懒加载 (React.lazy + Suspense)

按需加载组件可减少初次加载时间:

const SomePage = React.lazy(() => import('./SomePage'));
7. 使用 key 优化列表渲染

确保 key 唯一且稳定,避免 diff 失败导致重渲染。

推荐:

id, uuid

不要用:

index

三、状态管理层级优化

8. 减少全局状态;保持状态尽可能本地化

不要把所有数据放到 Redux、MobX、Context

组件自己的状态放 useState

状态越靠上 → 重渲染越多。

9. 避免 Context 大范围使用

Context 变化会让所有消费者重新渲染。
优化方式:

  • 基于 selector 的 use-context-selector

  • 将 context 拆分更细

  • 使用 Zustand / Jotai / Recoil 等更高效的状态库

10. Redux 优化
  • 使用 reselect 缓存计算结果

  • 使用 useSelector 时拆分 selector

  • 使用 RTK(Redux Toolkit)减少不可预期行为

四、渲染内容优化(最重要的两类)

11. 大量数据渲染 → 虚拟列表(Virtualized List)

如:

  • react-window

  • react-virtualized

适用:
表格、聊天、长列表等上万行数据。

12. 大组件首次加载很慢 → 分包 + 懒加载

使用:

  • React.lazy

  • dynamic import

  • Webpack splitChunks

也可用:

  • 路由懒加载

  • 分模块打包

五、数据请求层优化

13. 避免重复请求(使用缓存)

库推荐:

  • SWR

  • React Query

支持自动缓存、重新加载、去重等功能。

14. 使用节流/防抖

搜索、滚动监听、表单输入等场景可以减少触发频率。

六、DOM 和浏览器层面优化

15. 使用 requestAnimationFrame 优化动画

避免在高频事件中同步操作 DOM。

16. 使用 Web Worker 处理重计算

避免主线程阻塞 UI:

heavyCalculateDataInWorker();
17. 使用 Suspense + 时间切片(React 18)

React18 的 concurrent mode 支持时间分片:

  • 分段渲染

  • 提升可响应性

最实用的“十条黄金法则”

  1. 能拆组件就拆组件

  2. 子组件包上 React.memo

  3. 回调用 useCallback

  4. 计算结果用 useMemo

  5. 大列表使用虚拟列表

  6. 按需加载路由 & 组件

  7. 避免 context 覆盖太广

  8. Redux 用 RTK,selector 拆细

  9. 避免在 render 中创建对象

  10. 状态下放(越靠下越好)

posted @ 2025-12-10 09:17  煜火  阅读(6)  评论(0)    收藏  举报