美文网首页
虚拟 DOM 和 DOM diff

虚拟 DOM 和 DOM diff

作者: 张德瘦嬢嬢 | 来源:发表于2020-12-24 11:09 被阅读0次

概念

  • 虚拟DOM

  • 是什么:其实就是个js对象
    虚拟 dom 是相对于浏览器所渲染出来的真实 dom 的,在react,vue等技术出现之前,我们要改变页面展示的内容只能通过遍历查询 dom 树的方式找到需要修改的 dom 然后修改样式行为或者结构,来达到更新 ui 的目的。
    这种方式相当消耗计算资源,因为每次查询 dom 几乎都需要遍历整颗 dom 树,如果建立一个与 dom 树对应的虚拟 dom 对象( js 对象),以对象嵌套的方式来表示 dom 树,那么每次 dom 的更改就变成了 js 对象的属性的更改,这样一来就能查找 js 对象的属性变化要比查询 dom 树的性能开销小。

  • 优点:1. 减少不必要的DOM操作 2. 能跨平台渲染

  • 缺点:

需要额外的创建函数,如 React 中的 createElement 或者 Vue 中的 h可以通过 JSX 来简化成 XML 写法 ,但 是需要额外的构建过程,严重依赖打包工具

  • DOM diff

  • 是什么:一个函数:虚拟DOM的对方算法的一个函数patches=patch(oldVNode,newVNode)

  • 优点:减少DOM操的次数(只需要操作变化的节点)

  • 缺点:同级节点对比存在bug(key)

关于DOM的谣言:DOM操作慢,虚拟操作DOM快?

  • 慢是相比于原生js的api,
  • 但是任何基于DOM库的(Vue/React)都不可能在操作DOM时比DOM快

为什么有谣言呢?

  • 因为确实有时 虚拟DOM快:比如下面的例子

虚拟DOM长什么样子

  1. 在React中的虚拟DOM
const vNode = {
  key: null,
  props: {
    children: [
      {type: 'span', ...},
      {type: 'span', ...}
    ],
    className: "red",
    onClick: ()=>{}
  },
  ref: null,
  type: "div",
  ...
}
  1. 在Vue中的虚拟DOM
const vNode = {
  tag: 'div',
  data: {
    class: 'red',
    on: {
      click: ()=>{}
    }
  },
  children: [
    {tag: "span", ...},
    {tag: "span", ...}
  ],

创建虚拟DOM

  1. React
  createElement('div',{className:'red',onClick:()=> {}},[
    createElement('span', {}, 'span1'),
    createElement('span', {}, 'span2')
  ]
)
// 通过 JSX 简化
<div className="X" onClick="{()=> {}}">
    <span>span1</span>
    <span>span2</span>
</div>
//  通过 babel 转为 createElement 形式
  1. Vue
//  只能在 render 函数里得到 h
h('div', {
  class: 'red',
  on: {
    click: () => { }
  },
}, [h('span',{},'span1'), h('span', {}, 'span2'])
   
   
 // 通过简化JSX
<div class="red" @click="fn">
  <span>span1</span>
  <span>span2</span>
</div>
// 通过 vue-loader 转为 h 形式

DOM diff

  1. 把虚拟DOM想象成树形
    举例一:
<div :class="x">
    <span v-if="y">{string1}</span>
    <span>{string2}</span>
</div>
image

当数据变化,x从red变为green

image

此时DOM diff发现:

  • div标签类型没变,只需要更新div对应的DOM的属性。
  • 子元素没变不更新
    举例二:
    当数据变化,y从true变为false
    image
    DOM diff发现:
  • div没变,不用更新。
  • 子元素1标签没变,但是children变了,更新DOM 内容
  • 子元素2不见了,删除对应的DOM
    DOM diff总结:
  • 虚拟 DOM 的对比算法
  • 一个被称为 patch 的函数
  • patches = patch(oldVNode, newVNode)
  • patches 就是要运行的 DOM 操作
    即给两个虚拟节点,返回对应的 DOM 操作
    DOM diff优点:
  1. 能减少不必要的DOM操作
    2.能跨平台渲染
    DOM diff缺点:
  2. 需要额外的创建函数,如createElement或h,但是可以通过JXS来简化成XML写法。
  3. 同级节点对比存在bug🔜解决方法:用Key值进行区分

举个栗子

如不加key的三个同级input标签,分别输入不同value:1、2、3,然后点击删除第二个,会发现留下的两个input中,value值是1、2而不是1、3。

image

点击删除2,你以为2被删除了,结果却是:

image

因为中间的删除第三个取代第二个的位置这个是我们人类认为的逻辑,计算机认为的逻辑是:第二个的改变,第三个的删除(神奇的算法逻辑)。

如何解决?

相关文章

  • 虚拟dom和diff算法

    虚拟DOM和diff算法 diff:精细化比对最小量更新 真实DOM和虚拟DOM 虚拟DOM:用JavaScrip...

  • 虚拟 DOM 和 DOM diff

    visual Dom是什么? 虚拟DOM其实就是,像拥有类似dom的一系列属性的对象,包括:标签名,标签上的属性,...

  • 虚拟DOM和DOM diff

    DOM总结 虚拟DOM是什么 一个能代表DOM树的对象,通常含有标签名、标签上的属性、事件监听和子元素们,以及其它...

  • 虚拟DOM和DOM diff

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

  • 虚拟 DOM 和 DOM diff

    概念 虚拟DOM 是什么:其实就是个js对象虚拟 dom 是相对于浏览器所渲染出来的真实 dom 的,在react...

  • 虚拟 DOM 和 DOM diff

    1.虚拟 DOM 与页面DOM元素对应的对象。包含标签名、标签上的属性、事件监听及其子元素。本质是一个JS对象。 ...

  • Diff 算法、key

    概念 DOM diff 就是对比两棵虚拟 DOM 树的算法。当组件变化时,会得到一个新的虚拟 DOM,diff 算...

  • 面试题集(2)

    为什么虚拟dom会提高性能? 参考答案 虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算...

  • react VS Vue diff算法

    react diff diff算法的作用:数据更改,生成相应的虚拟DOM,与真实DOM作对比,通过diff算法,对...

  • 深入理解react中的虚拟DOM、diff算法

    文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 Re...

网友评论

      本文标题:虚拟 DOM 和 DOM diff

      本文链接:https://www.haomeiwen.com/subject/svrunktx.html