React性能优化(以及React的render过程)

前言

在了解React的性能优化之前,首先要对React的render过程有了解。

Render

对React有了解的都知道,render的渲染分为初始化渲染和更新渲染。初始化渲染就是在页面初始化的时候调用根组件下所有组件的render方法,如下图,一个DOM树表示根组件与各组件之间的联系,绿色是代表已经渲染的。


现在讲的这种情况,如果我们只需要对某一个子组件进行更新,如图绿色代表的是需要更新的子组件:


而该子组件依靠于父组件传过来的props进行更新渲染,因此,我们的理想状态就是只更新此子组件与其父组件这条路径,如图绿色所示:


然而,由于最上层的根组件需要重新render,必定导致其所有子组件都要重新render,再将生成的虚拟dom进行对比,如果不变则不更新真实的dom树。即使有些组件的并没有改变,没有导致视图改变的props改变,但是也要重新render对虚拟dom树进行对比,因为React难以置信简单地将默认行为设计为每次都重新render生成新的虚拟dom进行对比,因为在shouldcomponentupdate的方法里面默认是返回true,这样的对比明显是浪费的。如图黄色代表浪费的render:


这里需要注意的是:

1、执行了render方法不代表会更新dom树,在react当中你使用了setstate更新了state或者改变了传入的props,都会执行render方法,执行了render方法以后,才会生成dom树进行对比,如果dom有差异才会进行构建新的渲染树,更新对应的dom,否则,不会更新。因此,生成虚拟dom树进行对比是在render函数执行了之后进行,而不是执行之前。

2、拆分组件有助于性能优化。组件拆分了,各组件之间的耦合性小了,某个子组件需要更新的时候,牵涉到其他的组件就少,就能减少牵一发而动全身这种情况。

React性能优化

从上面介绍的render过程可以得知,对react的性能进行优化,其实就是减少不必要的render。

1、shouldcomponentupdate

在react的生命周期当中,如果state或者props发生了改变,此生命周期函数都会被调用,即使视图没有更新,true就是会执行render,false就不执行,而react对此方法默认是返回true,因此如果我们不处理就会默认重新render,就会导致一些不必要render,因此我们可以对shouldcomponentupdate()进行处理。

shouldComponentUpdate(object nextProps, object nextState)

该方法接收两个参数,nextprops和nextstate分别代表即将更新的props和state,因此我们可以在该函数里面进行比较,如果props或state对应的属性没有改变,则返回fales,否则true。

2、PureCompontent

purecompontent纯组件是react15.3新增的一个PureCompontent类,我们可以以es6的方式去定义纯组件。

为什么使用PureCompontent?

使用了PureCompontent之后,会对shouldcomponentupdate进行处理,在此方法当中会对需要重新render的state和props进行浅比较,注意是浅比较,因此如果是引用类型在纯组件这里比较可能会达到非预期效果,就是状态有改变但是视图不更新。浅比较的结果如果有变化,就会进行接下来的生命周期,否则不会,就可以节省不必要的render、diff对比。

注意问题:

PureComponent只能说是一种泛泛的性能问题解决方法,并不具备很高的定制性,最好的方式还是自己去处理组件的shoudComponentUpdate。并且,PureComponent的浅对比shallowEqual在对比引用值的时候,也会存在问题。

3、无状态组件

无状态组件又被叫做函数式组件,这种组件没有状态,没有生命周期,只是简单的接受 props 渲染生成 DOM 结构。无状态组件非常简单,开销很低,如果可能的话尽量使用无状态组件。

// es6
const HelloMessage = (props) => <div> Hello {props.name}</div>;
render(<HelloMessage name="John" />, mountNode);
//es5
export default function HelloMessage(props) {
  return <div>Hello {props.name}</div>;
}

注意:无状态组件是没有经过react的生命周期实例化的,因此没有自己的state,只能通过父组件传入props,也不需要强制绑定this。


参考文章:

https://segmentfault.com/a/1190000007811296#articleHeader14

https://segmentfault.com/a/1190000013099247

https://www.jianshu.com/p/6e6f3b270592

猜你喜欢

转载自blog.csdn.net/chiuwingyan/article/details/80204966