react 组件渲染分为初始化渲染和更新渲染,当我们更新某个组件的时候,只是想关键路径上组件的render,但react的默认做法是调用所以组件的reder,再生成虚拟dom进行对比,如不变则不进行更新。这样的render和虚拟DOM的对比明显是在浪费。
React的优化是基于shouldComponentUpdate的,该生命周期默认返回true,所以一旦prop或state有任何变化,都会引起重新render。shouldComponentUpdate 有两个参数,一个是nextProps,一个nextState 。根据渲染流程,首先会判断shouldComponentUpdate(SCU)是否需要更新。如果需要更新,则调用组件的render生成新的虚拟DOM,然后再与旧的虚拟DOM对比(vDOMEq),如果对比一致就不更新,如果对比不同,则根据最小粒度改变去更新DOM;如果SCU不需要更新,则直接保持不变,同时其子元素也保持不变。
下面有几条优化的建议:
- this.handleChange.bind(this,id) (请将方法的bind一律置于constructor);
- 复杂的页面不要在一个组件里面写完;
- map里面添加key,并且key不要使用index(可变的);
- 请尽量使用const element;
- 尽量少用setTimeOut或不可控的refs、DOM操作;
6.props和state的数据尽可能简单明了,扁平化;
官方提供的性能检测工具:React.addons.Perf和react-perf-tool ;
性能优化方法:1)es6写法;
var shallowCompare = require('react-addons-shallow-compare');
export class SampleComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState);
}
}
2)es7 修饰符:
import pureRender from "pure-render-decorator"
...
@pureRender
3)更简便的方式:
function shallowCompare(instance, nextProps, nextState) {
return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState);
}
4)使用react-addons-pure-render-mixin 插件,代码如下:
;
5)react 15.3以后用React.PureComponent - 一个可继承的新的基础类, 用来替换react-addons-pure-render-mixin;代码如下:
;
以上的方法都是浅比较,如果结构比较复杂,则需要使用immutable.js 。
本文参考:https://segmentfault.com/a/1190000007811296 和 https://wulv.site/2017-05-31/react-purecomponent.html ,感谢分享;