redux高阶运用

1. diff算法

React组件的核心思想是:

  • 将页面拆分为一个个组件,一个组件还可能嵌套更小的组件,每个组件都有自己的数据,当某个组件的数据发生变化时,更新该组件的部分视图。
  • 更新的过程是由数据驱动的,新的数据自该组件顶层向下流向子组件,每个组件调用自己的render方法得到新的视图,并与之前的视图diff比较差异,完成更新,这个过程就是reconciliation-调和

虚拟DOM基本原理:
用纯js对象来模拟DOM树,每当更新时,根据组件的render方法计算出新的虚拟DOM树,并与之前的虚拟DOM树作比较,得到一个差异补丁,最后隐射到真正的DOM树上完成视图更新,以减少操作DOM的次数

diff算法:前端很少跨越层级移动DOM元素,只会对虚拟DOM中同一层级的元素进行比较,这样算法复杂度就可以达到O(n)

diff碰到列表会有问题
发现列表元素不同时,就会对其进行重渲染,但是可能只是进行了插入操作,只需要进行移动操作即可,需要定义key属性,diff时就会去查找是否有相同的key元素,比较它们是否完全相同,若是则会复用该元素,免去不必要的操作
不推荐使用数组的index作为key,因为如果数据重排,index并不能起到唯一标识的作用,每次视图元素都会重新渲染

diff会帮我们计算出虚拟DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面,从而保证了每次操作更新后页面的高效渲染
传统diff算法循环递归对节点进行依次比较,算法复杂度为O(n3),React可以转化为O(n)复杂度

2.diff策略

diff算法的三个策略

  • DOM节点的跨层级的移动操作特别少,可以忽略不计
  • 拥有相同类的两个组件会生成相似的树形结构,拥有不同类的两个组件会生成不同的树形结构
  • 对于同一层级的一组子节点,它们可以通过唯一id进行区分

2.1 tree diff

对树进行分层比较,两棵树只会对同一层次的节点进行比较,即同一个父节点下的所有子节点,当发现节点已经不存在时,则该节点及其子节点会被完全删除掉,不会用于进一步的比较,这样只需要对树进行一次遍历

当出现节点跨层级移动时,并不会出现想象中的移动操作,而是移除不存在的节点及其子节点,创建存在的节点

注意:在开发组件时,保持稳定的DOM结构会有助于性能的提升,可以通过CSS隐藏或显示节点,而不是真正移除或添加DOM节点

2.2 component diff

组件间比较:

  • 同一类型组件,按照原策略继续比较虚拟DOM树
  • 将该组件判断为dirty component,替换整个组件下的所有子节点
  • 同一类型组件,可能虚拟DOM完全没有变化,用户通过shouldComponentUpdate来判断组件是否需要进行diff算法

即不同组件则,直接替换掉组件下的所有子节点

2.3 element diff

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容