这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战
前言
VirtualDOM是什么,VirtualDOM Diff高效的原因
Virtual DOM Diff
Virtual DOM如何提高性能
- 我们将render产生的VirtualDOM简称'Vdom'
- 通常调用setState方法触发Vdom更新
- 通过对比新旧'Vdom',确定最优实现新'Vdom'所需的操作
这里的Virtual DOM diff 也是指第三步。不被我们平时所在意的一个步骤。
Virtual DOM Diff的层次
- 组件级别的比较
- 元素级别的比较
因为我们通常一个HTML节点是一棵完整的树,完整的树遍历时间复杂度为O(n^3)
而Virtual DOM对HTML层级节点的划分,遍历所有节点的时间复杂度为O(n^0)
这也是使得Virtual DOM比较高效的原因之一
Component Diff
R - 入口App A - 配置页面1 D - 配置页面2 G - 配置页面3
当前需求把D(配置组件2)转换为G(配置页面3)
虽然D、G 组件 有相同的EF,但是这里还是会把D、E、F组件全部删掉,再去重新创建G、E、F组件。(因为有相同的EF子组件毕竟还是小概率事件,现实场景中,EF下可能有很多个子组件,难以做到一个一个全部比对,做到了也十分低效,不如全部删掉,这个只是个人感受,不做理论的论证,先给个定论,感兴趣有时间可以探讨)
Element Diff
创建、移动、删除子节点 对应了DOM操作中的创建、移动、删除
创建节点
create: function (child, afterNode,mountImage){
return makeInsertMarkup(mountImage,afterNode,child._mountIndex);
}
复制代码
删除节点
removeChild: function (child, node){
return makeRemove(child, node)
}
复制代码
移动节点
1-2-3 =》 3-1-2
react实现是把1挪到3后面,再把2挪到3后面,这样的操作是比较低效的,尽量要规避把最后一个节点移动到最前面的情况
协调reconciliation
最后一句话this process is called reconciliation
Virtual DOM diff是React协调中的一个环节,而在React15的版本中这个协调叫做栈协调(Stack Reconciler)
过程回顾
- render 执行render
- Virtual Diff 比较Virtual dom
- commit 确定需要更新则执行更新 (不可阻断)
因不可阻断,如果执行中用户产生了交互行为,页面可能相应不过来,发生卡顿。
React16推出了一个新的协调方法
总结
-
Virtual DOM本质是对UI节点的抽象。只是在Web开发中,具体化为对HTML DOM节点的抽象。这也是前端逐渐跨平台化的一种体现。
-
Virtual DOM比原生高效的原因,一是Diff算法的高效,实现了高效的更新,另一个是可维护性和编程思维上的高效。
参考链接
官网Virtual Dom reactjs.org/docs/faq-in…
Virtual DOM Node mithril.js.org/vnodes.html
VDom与 DOM 的区别 reactkungfu.com/2015/10/the…
PS: React的水越来越深了,感觉已经不太适合用来玩这种短平快的更文了。换一个模块试试吧。