从底层设计开始,React就充分考虑了性能问题,在更新UI时,他使用很聪明的技巧来尽可能减少耗时的DOM操作。
一 子级校正
当你改变了组件的状态时,会触发一次新的重绘,React会构建一个虚拟的DOM来呈现UI的状态,并与当前的虚拟DOM相对比,得出差异进而计算出哪些DOM元素需要进行增加,删除,更改等操作,这个过程就是子级校正。
1.批处理
React中调用setState之后不会立即触发更新,而是将其标为“脏”状态,然后使用轮询对内容进行批量绘制。轮询结束以后,React会对标记为脏的组件及其子组件进行重绘,所有后代节点的render方法都会被调用,哪怕他们并没有发生变化。这个过程看上去有些浪费,但速度是很快的,因为只是对虚拟的DOM进行render,并没有操作真实的。
2.优化
可以使用shouldComponentUpdate()方法阻止子树的重绘,只有个别情况下会使用这种方法,应在整体分析是否需要进行性能的调整,一级哪里需要调整后再使用。当它返回true时,则进行重绘,返回false时,不再重绘。
二 React Perf
这是一个分析工具,会对应用做一个整体性能的分析,帮助寻找哪里需要优化,正是这些地方需要使用shouldComponentUpdate。
1.方法
Perf.start() Perf.stop()开始/结束测量,分别放在渲染前后; Perf.printInclusive() 打印消耗的全部时间; Perf.printExclusive() ; Perf.printWasted()浪费的时间:棰没有做任何渲染的消耗。如过浪费时间较多,无法接受时就需要进行性能优化。
2 shouldComponentUpdate
shouldComponentUpdate接受nextProps()和nextState()作为参数,可以用来比较新旧的属性值,当有所变化时选择更新,简单的值还可以,若比较两个对象中层级很深的属性开销就很大了。而使用不可变值会让开销变小,速度快且可靠。
3 shallowCompare插件
可配合shouldComponentUpdate一起使用,比较组件的props和state,并返回组件是否发生了变化,在以下情况下可以使用:
1⃣️组件是纯粹的,即相同的props和state下渲染结果相同;2⃣️使用了不可变值来处理状态。
三 总结
React的子级校正会在轮询后对标记为脏的组件及其后代重新渲染,对于未更改状态的后代来说是种浪费,优化主要通过shouldComponentUpdate()来实现,在这过程中,可使用perf来判断性能是否需要优化,并可借助shallowCompare得出状态是否改变。