React 组件的性能优化

虽然react已经提供了很好的渲染性能,但要让程序发挥到极致,还需要进一步了解性能优化的方法,本章节主要从三个方面讲解:

  • 单个react组件的性能优化
  • 多个react组件的性能优化
  • 用reselect提高数据获取性能

单个react组件的性能优化

react渲染之所以快,是因为利用Virtual DOM来计算出DOM树的最少修改,只渲染修改的部分,而不是所有。

如果能够在开始计算Virtual DOM之前就可以判断结果不会变化,那干脆不要再去计算和比较,速度就会更快。

借助react perf工具,发现浪费的渲染时间

react perf 这个工具的安装和使用这里不再讲述。

这个工具记录在点击start和stop按钮之间的所有react的渲染,如果有组件计算Virtual DOM之后,和之前的Virtual DOM相同,就认为是一次浪费。

这里所说的浪费是计算Virtual DOM的浪费,并不是访问DOM的浪费。

可以借助这个工具清晰的知道哪个组件被无意义的渲染了,达到优化性能的目的。

性能优化的时机

过早的优化是万恶之源—–高德纳

很多人对这句话有个错误的认识,认为高前辈不让做过早的优化,很显然我们误会老高了,他的全句是这样的

“我们应该忘记忽略很小的性能优化,可以说97%的情况下,过早的优化是万恶之源,而我们应该关心对性能影响最关键的那另外3%的代码”—–高德纳

前辈的这句话有三个重要的点:

1、不要把精力放在对整体性能优化提高不大的代码上,而对于性能有关键影响的部分,优化并不嫌早。

2、所谓过早的优化,是指在没有任何数据体现下开发者对性能优化的猜测,没有可测量的性能指标,完成优化后,也不知道是否达到了预期的结果。

3、高德纳认为过早的优化是万恶之源,是因为这些优化往往让代码过于复杂和难于维护,但如果早期的优化能够让代码结构更加合理更加容易维护,为什么不呢?

多个react组件的性能优化

多个组件和单个组件一样,都需要经历组件装载、更新、卸载三个步骤。

其中装载这个部分没有什么可以性能优化的事情做,卸载部分是会出现组件加载后添加的事件监听等收尾工作,也没有太多的可优化空间。

重要的放在更新过程。

react的调和过程

什么叫调和?

就是render后和更新后,生成的这个树,相互比较找不同,这个找不同的过程就叫调和。

react怎么找不同呢?

1、先检查两个节点的类型

这个类型分为两类:一类是dom元素类型,就是div span; 另一类是react组件,也就是利用react库定制的类型。

1.1 如果不同

举个例子,组件包裹外层原来是div,更新为span,这个时候,react一看这完全不相同,那后面的子节点也别看了,直接重新构建一份吧,这就造成了性能上面的浪费。

解决办法:作为开发者尽量不要改动做为包裹层的类型。

1.2 如果相同

上面说了类型有两种,如果是dom类型加同,就只对比这个节点的属性和内容,然后更新修改的部分,如下面的代码

原来的:

<div style=>hello</div>

更改后的:

<div style=>hello</div>

DOM节点类型没变,只需要修改它的属性,变动少。

另外一种类型是react组件类型,它更新时只能根据新节点的props去更新原来的组件,引发这个组件实例的更新过程,按照下面的顺序引发下面的函数:

  • shouldComponentUpdate
  • componentWillReceiveProps
  • componentWillUpdate
  • render
  • componentDidUpdate

这个时候就需要合理的使用shouldComonentUpdate函数了,如果没有必要渲染,就返回false。

好了,对比了根节点之后,会对这个根节点的每一个小节点重复相同的动作,该更新更新,该创建创建。

2、key的作用

key就相当于组件的身份证号,标识组件的位置,react可以根据根据key值的有无变化,从而决定是否更新它。

这个时候注意个问题,在循环一个数组时,不能以数组的下标做为key值定义每个子组件,key值变来变去的无规则也会引起不必要的重新加载或者更新创建。