浅谈虚拟DOM与DOM diff

1.什么是虚拟DOM?

是一个能代表DOM 树的对象,通常含有标签名、标签上的属性、事件监听和子元素们,以及其他属性

实际上虚拟DOM是与真实的DOM对应的一个概念,在以下两种情况下虚拟DOM比真实DOM快的,或者说有如下两种优点

  1. 可以减少DOM操作:虚恢DOM可以将多次操作合并为一次操作,比如你添加1000个节点,却是一个接一个操作的;虚拟DOM借助DOM diff可以把多余的操作省掉,比如你添加1000个节点,其实只有10个是新增的
  2. 跨平台:虚拟DOM不仅可以变成 DOM,还可以变成小程序、iOS应用、安卓应用,因为虚拟DOM本质上只是一个JS对象

虚拟DOM有缺点吗?

需要额外的创建函数,如 createElement 或 h,但可以通过JSX来简化成XML写法,不过有需要对外部插件的依赖。

结论:

当你的DOM数量规模在几千数量级的时候,使用虚拟DOM是很好的选择,它会很好的优化一些多余的操作,从而提高性能;但是数量级在万级别或者几十万级别的时候虚拟DOM并不会表现很好,甚至会因为自身的一些算法而变得时间过长,比如React

2.什么是DOM diff

假如把虚拟DOM想象成树形

<div :class='x'>
    <span v-if='y'>{{string}}</span>
    <span>{string2}</span>
</div>
DOM树.png

当属性变化时,比如 class属性 从 x 变为 red,于是DOM diff发现该元素标签类型没变,只需要更新 div 对应的 DOM的属性即可,并且子元素没变,无需更新

当数据变化时,比如说 y 从true 变成 false时候,DOM diff 发现div没变,子元素1标签没变,但是children文字变了,更新DOM内容,删除span2

什么是DOM diff
  • 就是一个函数,我们称之为 patch

  • patches = patch(oldVNode,newVNode)

  • changed 就是要运行的DOM操作,可能长这样:

  •   [
          {type:'INSERT',vNode:...},
           {type:'TEXT',vNode:...},
          {type:'PROPS',propsPatch:...},
      ]
    
DOM diff 大致逻辑
  1. tree diff:
  • 将新旧两棵树逐层去对比,找出哪些节点需要更新
  • 如果节点是组件就看Component diff
  • 如果节点是标签就看Element diff
  1. Component diff
  • 如果节点是组件,就先看组件类型
  • 类型不同直接替换(删除日的)
  • 类型相同则只更新属性
  • 然后深入组件做Tree diff(递归)
  1. Element diff
  • 如果节点是原生标签,则看标签名
  • 标签名不同直接替换,相同则只更新属性
  • 然后进入标签后代做Tree diff(递归)
DOM diff 的缺点

同级节点对比存在bug,会出现识别错误的问题

这里便引出了一个经典问题---Vue2.0 v-for 中 :key 到底有什么用?

这里参考方应杭的文章https://www.zhihu.com/question/61064119/answer/766607894

两篇深入的阅读

React虚拟Dom和diff 算法:https://juejin.cn/post/6844903529161850893

React 源码剖析系列-不可思议的react diff:https://zhuanlan.zhihu.com/p/20346379

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 概念 虚拟DOM 是什么:其实就是个js对象虚拟 dom 是相对于浏览器所渲染出来的真实 dom 的,在react...
    张德瘦嬢嬢阅读 2,924评论 0 0
  • visual Dom是什么🧐 虚拟DOM其实就是,像拥有类似dom的一系列属性的对象,包括:标签名,标签上的属性,...
    Adder阅读 1,072评论 0 2
  • 文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 Re...
    李轻舟阅读 8,230评论 2 14
  • 虚拟DOM是什么? 一个能代表DOM树的对象,通常含有标签名、标签上的属性、事件监听和子元素们,以及其他属性。 虚...
    Marshall3572阅读 1,566评论 0 1
  • 由于源码中diff算法掺杂了太多别的功能模块,并且dom diff相对于之前的代码实现来说还是有些麻烦的,尤其是列...
    Nealyang阅读 6,591评论 2 10