React 性能优化总结

发布于 2024-07-10 11:11:29 字数 4841 浏览 13 评论 0

一、重新认识 render

react 的组件渲染分为初始化渲染和更新渲染,在初始化渲染的时候会调用根组件下的所有组件的 render 方法进行渲染,如下图(绿色表示已渲染,这一层是没有问题的)。

但是当我们要更新某个子组件的时候,如下图的绿色组件(从根组件传递下来应用在绿色组件上的数据发生改变)

我们的理想状态是只调用关键路径上组件的 render

但是 react 的默认做法是调用所有组件的 render ,再对生成的虚拟 DOM 进行对比,如不变则不进行更新。这样的 render 和虚拟 DOM 的 对比 明显是在浪费,如下图(黄色表示浪费的 render 和虚拟 DOM 对比)

Tips

  • 拆分组件是有利于复用和组件优化的
  • 生成虚拟 DOM 并进行比对发生在 render() 后,而不是 render()

二、更新阶段的生命周期

  • componentWillReceiveProps(object nextProps) :当挂载的组件接收到新的 props 时被调用。此方法应该被用于比较 this.propsnextProps 以用于使用 this.setState() 执行状态转换。(组件内部数据有变化,使用 state ,但是在更新阶段又要在 props 改变的时候改变 state ,则在这个生命周期里面)
  • shouldComponentUpdate(object nextProps, object nextState) : - boolean 当组件决定任何改变是否要更新到 DOM 时被调用。作为一个 优化 实现比较 this.propsnextPropsthis.statenextState ,如果 React 应该跳过更新,返回 false
  • componentWillUpdate(object nextProps, object nextState ) :在更新发生前被立即调用。你不能在此调用 this.setState()
  • componentDidUpdate(object prevProps, object prevState ) : 在更新发生后被立即调用。(可以在 DOM 更新完之后,做一些收尾的工作)

Tips

  • React 的优化是基于 shouldComponentUpdate 的,该生命周期默认返回 true ,所以一旦 propstate 有任何变化,都会引起重新 render

三、shouldComponentUpdate

react 在每个组件生命周期更新的时候都会调用一个 shouldComponentUpdate(nextProps, nextState) 函数。它的职责就是返回 truefalse ,true 表示需要更新, false 表示不需要,默认返回为 true ,即便你没有显示地定义 shouldComponentUpdate 函数。这就不难解释上面发生的资源浪费了

带坑的写法

  • {...this.props} (不要滥用,请只传递 component 需要的 props ,传得太多,或者层次传得太深,都会加重 shouldComponentUpdate 里面的数据比较负担,因此,也请慎用 spread attributes(<Component {...props} />))
  • ::this.handleChange()。(请将方法的 bind 一律置于 constructor)
  • 复杂的页面不要在一个组件里面写完
  • 请尽量使用 const element
  • map 里面添加 key ,并且 key 不要使用 index (可变的)
  • 尽量少用 setTimeOut 或不可控的 refsDOM 操作
  • 数据尽可能简单明了,扁平化

四、性能检测工具

React.addons.Perf

react 官方提供一个插件 React.addons.Perf 可以帮助我们分析组件的性能,以确定是否需要优化

react16 以前需要在项目中配置, react16 以后请看这篇文章,直接打开控制台的 perf 选项测试 https://reactjs.org/docs/optimizing-performance.html

react16 之前配置

  • 安装 react 性能检测工具 npm i react-addons-perf --save ,然后在 ./app/index.js
// 性能测试
import Perf from 'react-addons-perf'
if (__DEV__) {
    window.Perf = Perf
}
  • 打开 console 面板,先输入 Perf.start() 执行一些组件操作,引起数据变动,组件更新,然后输入 Perf.stop() 。(建议一次只执行一个操作,好进行分析)
  • 再输入 Perf.printInclusive 查看所有涉及到的组件 render ,如下图(官方图片)

或者输入 Perf.printWasted() 查看下不需要的的浪费组件 render

优化前

优化后

五、参考文章

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

如果没有你

暂无简介

0 文章
0 评论
24 人气
更多

推荐作者

我们的影子

文章 0 评论 0

素年丶

文章 0 评论 0

南笙

文章 0 评论 0

18215568913

文章 0 评论 0

qq_xk7Ean

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文