✨ 个人主页:CoderHing
🖥️ React .js专栏:React .js React组件化开发(二)
🙋♂️ 个人简介:一个不甘平庸的平凡人🍬💫 系列专栏:吊打面试官系列 16天学会Vue 11天学会React Node专栏
🍀 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀️
👉 你的一键三连是我更新的最大动力!❤️
❤️ 本文约 6470 字,预计阅读需要 20 分钟 ❤️
目录
一、React性能优化SCU
React更新机制
-
React渲染流程:
-
在render函数中返回一个jsx
-
jsx创建出来对应的React.createElement
-
这些element最终会形成一个树结构(对应的话就是虚拟DOM)
-
最后React会根据虚拟DOM去渲染出来一个真实DOM
-
-
React更新流程:
-
当前props/state发生改变
-
render函数重新执行
-
之后产生一棵新的DOM树(新的树结构)
-
在新旧树结构中进行diff算法来对比差异
-
之后计算出差异的点进行一系列的更新
-
最后把需要更新的地方更新到真实的DOM中
-
React更新流程
-
React在props或state发生改变时,会调用React的render方法,会创建出一棵不同的树.
-
React需要基于这两棵不同的树之间的差异来判断如何有效的更新UI:
-
如果一棵树参考另外一棵树进行完全比较更新,那么即使是最先进的算法(算法的复杂程度为O(n²)),其中n是树中元素的数量
-
如果React中使用了该算法,那么展示1000个元素所需要执行的计算量将在亿的量级范围内.
-
这个开销很大,那么React更新性能将会变得十分低效.
-
-
React对这个算法进行了优化,将其优化成了O(n),如何优化的呢?
-
同层节点之间相互比较,不会跨节点比较
-
不同类型的节点,产生不同的树结构
-
开发中,可以通过key来指定哪些节点在不同的渲染下保持稳定.
-
keys的优化
-
我们在之前遍历列表时,总是会提示一个警告,让我们加入一个key属性:
-
方式一:在最后位置插入数据
-
这种情况有没有key其实意义并不是很大
-
-
方式二:在前面插入数据
-
这种情况在没有key的情况下,所有的li都会进行修改
-
-
当子元素(li)拥有key时,React使用key来匹配原有树上的子元素以及最新树上的子元素
-
在这种场景下,key为111和222的元素仅仅进行了位移,不需要进行任何的修改
-
将key为333的元素插入到最前面的位置即可
-
-
key的注意事项
-
key应该是唯一的
-
key不要使用随机数(随机数会在下一次render时,重新生成一个新数)
-
使用index作为key,对性能是没有优化的
-
render函数被调用
-
嵌套案例:
-
在App中,我们增加了一个计数器的代码
-
当点击+1时,hUI重新调用App的render函数
-
而当App的render函数被调用时,所有的子组件的render函数都会被重新调用
-
-
-
那么,在之后的开发中,我们只是修改了App中的数据,是,所有的组件都需要重新render,进行diff算法,性能肯定非常低:
-
事实上,很多的组件是没有必要去重新render的
-
它们调用render应该有一个前提,就是依赖的数据(state,porps)发生改变,再去调用render方法;
-
-
那么怎么来控制render方法是否被调用?
-
通过shouldComponentUpdate方法即可
-
shouldComponentUpdate
-
React提供了一个生命周期方法 shouldComponentUpdate(简称:SCU)这个方法接收参数,并且需要有返回值:
-
该方法有两个参数:
-
nextProps => 修改之后,新的props属性
-
nextState => 修改之后,新的state属性
-
-
该方法返回值是一个boolean类型:
-
返回值为true时,就需要调用render方法
-
false则不需要调用
-
默认返回是true,也就是只要state/props发生改变,就会调用
-
-
比如我们在App中增加一个message属性:
-
jsx中并没有依赖message,那么她的改变不应该引起重新渲染
-
但是因为render监听到了state中的改变,就会重新render,所以最后render方法还是被调用了.
-
-
PureComponent
-
如果所有的类都需要手动去实现 shouldComponentUpdate,那么会给开发带来很多的重复工作量
-
我们设想一下shouldComponentUpdate中的各种判断目的是什么?
-
props/state中的数据是否发生了改变,来决定shouldComponentUpdate返回true/false
-
-
事实上React已经考虑到了这一点,所以React已经默认帮我们实现好了,那么如何实现的?
-
将class继承自PureComponent
-