欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 【React】React 性能优化

【React】React 性能优化

2025/2/26 17:24:00 来源:https://blog.csdn.net/XiugongHao/article/details/145801386  浏览:    关键词:【React】React 性能优化

一、React 更新流程(结合 React 18/19 底层原理)

React 在props 或者 state 发生改变时,会调用 React 的render 方法,创建一颗不同的树。

React 18 的更新流程基于 Fiber 架构并发模式(Concurrent Mode),核心分为三个阶段:

  1. 调度阶段(Scheduler)

    • 优先级调度:通过 lane 模型管理任务优先级(如用户交互事件优先级高于数据请求),调度器(Scheduler)将任务分片为 5ms 的时间片。
    • 可中断性:通过 shouldYield() 判断时间片是否用完,中断低优先级任务,确保主线程不阻塞。
  2. 协调阶段(Reconciler)

    • Fiber 树构建:对比新旧虚拟 DOM(Diff 算法),生成副作用链表(如插入、更新、删除标记)。React 18 支持增量渲染,通过 workInProgress 双缓存树实现异步可中断的协调过程。
    • 并发更新:高优先级更新可中断低优先级任务,例如用户输入时暂停长列表渲染。
  3. 提交阶段(Renderer)

    • 同步 DOM 更新:根据副作用链表批量更新真实 DOM,此阶段不可中断。
    • 自动批处理:React 18 对事件回调、Promise 等场景的多个 setState 自动合并为单次渲染。

React 19 改进

  • 引入更细粒度的 服务端组件(Server Components),支持流式渲染和选择性注水(Hydration)。
  • 优化错误边界处理,提供 onCaughtError 等 API 自定义错误上报。

二、Keys 的优化原理

Key 的作用

  • 唯一标识:帮助 React 在 Diff 过程中识别元素身份,减少不必要的 DOM 操作。
  • 状态保留:相同 Key 的组件实例会被复用,避免内部状态(如表单输入)丢失。

优化实践

  • 避免索引作为 Key:动态列表中使用索引会导致元素错位(如删除中间项),而且对性能没有优化。
  • 唯一稳定值:优先使用数据 ID(如 item.id),若无则用哈希值(如 item.name + timestamp)。
  • 不要使用随机数:随机数在下一次 render 时,会重新生成一个数字。

底层机制

  • Diff 算法:通过 Key 快速匹配新旧元素,仅对移动、新增、删除的节点操作 DOM,复杂度从 O(n³) 降至 O(n)。
    • 同层节点之间相互比较,不会垮节点比较;
    • 不同类型的节点,产生不同的树结构;
    • 开发中,可以通过key来指定哪些节点在不同的渲染下保持稳定

在最后插入数据有无key 意义不大。前面插入数据如果没有 key 后面的节点都需要修改,如果有key ,原节点只需要移动,不需要修改。


三、Render 函数的调用机制

  1. 触发条件

    • State/Props 变更:父组件渲染(父组件render 调用,所有子组件的render 都会重新调用)、setState、Context 变化等。

    • Force UpdateforceUpdate() 跳过 shouldComponentUpdate(SCU) 生命周期,进行强制渲染。

      shouldComponentUpdate目前已经过时(类组件相关API均已过时)

  2. React 18 优化

    • 自动批处理:事件处理函数中的多次 setState 合并为单次渲染。
    • 并发渲染:低优先级更新可能被中断,避免界面卡顿。
  3. 性能陷阱

    • 无意义渲染:未优化的父组件渲染会触发所有子组件重新协调(即使 Props 未变)。

四、性能优化手段对比

方法适用场景原理注意事项
shouldComponentUpdateClass 组件手动比较新旧 Props/State,返回 false 阻止渲染。开发者工作量大。深比较可能性能更差,需权衡。
PureComponent(类组件继承PureComponent而不是Component)Class 组件自动浅比较 Props/State,仅第一层属性变化时渲染。底层使用shallowEqual方法。嵌套对象/数组变化可能漏检,需配合不可变数据。
React.memo函数组件类似 PureComponent,通过浅比较 Props 或自定义比较函数。默认浅比较,复杂对象需自定义比较函数(如 (prev, next) => prev.id === next.id)。

五、底层原理与最佳实践

  1. 浅比较(shallowEqual)的局限性

    • 仅检查对象第一层属性的引用是否相同,深层嵌套数据变化无法触发更新。
    • 解决方案:使用不可变数据(如 immer 库)或手动深比较(谨慎使用)或者直接赋值第一层一个新的引用对象(或者数组)。
  2. 高阶组件 Memo 的并发模式适配

    • React 18 的并发渲染中,memo 可减少非必要协调任务,提升高优先级更新的响应速度。
    • 自定义比较函数需轻量,避免抵消性能收益。
  3. 服务端组件(React 19)

    • 将静态部分(如布局)标记为服务端组件,减少客户端渲染负载。
    • 结合流式渲染(Streaming SSR),逐步注水提升首屏性能。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词