虚拟 DOM 和 DOM diff

什么是虚拟DOM

Virtual dom, 即虚拟DOM节点。它通过JS的Object对象模拟DOM中的节点,然后再通过特定的render方法将其渲染成真实的DOM节点。
虚拟DOM就是一个普通的JavaScript对象,包含了tag、props、children等属性。

虚拟dom的实现过程
  1. 通过js建立节点描述对象
  2. diff算法比较分析新旧两个虚拟DOM差异
  3. 将差异patch到真实dom上实现更新

在这里插入图片描述

如何生成一个dom这里我们拿react来举例

createElement
createElement 接受type, props,children三个参数创建一个虚拟标签元素DOM的方法。

function createElement(type, props, children) {
    return new Element(type, props, children);
}
`

这是一个react组件

const App=()=>{
 const yy=(e)=>{console.log(e)}
 return (
  <div style={{color:"red"}} className='xx' onClick={(e)=>{yy(e)}}>
   <span>hello</span>
   </div>
 )
}

这段代码会被babel-loader转化成下面的代码

"use strict";

const App = () => {
  const yy = e => {
    console.log(e);
  };

  return /*#__PURE__*/React.createElement("div", {
    style: {
      color: "red"
    },
    className: "xx",
    onClick: e => {
      yy(e);
    }
  }, /*#__PURE__*/React.createElement("span", null, "hello"));
};

render方法
render方法接受一个虚拟节点对象参数,其作用是:将虚拟DOM转换成真实DOM。

什么是DOM Diff

Dom diff
Dom diff 则是通过JS层面的计算,返回一个patch对象,即补丁对象,在通过特定的操作解析patch对象,完成页面的重新渲染。

Diff 算法
规则:同层比较
Diff算法中有很多种情况,接下来我们以常见的几种情况做下讨论:

  1. 当节点类型相同时,去看一下属性是否相同 产生一个属性的补丁包 {type:‘ATTRS’, attrs: {class: ‘list-group’}}
  2. 新的dom节点不存在 {type: ‘REMOVE’, index: xxx}
  3. 节点类型不相同 直接采用替换模式 {type: ‘REPLACE’, newNode: newNode}
  4. 文本的变化:{type: ‘TEXT’, text: 1}

比较两颗虚拟DOM树的核心diff方法接受oldTree旧DOM树、newTree新DOM树两个参数,根据两个虚拟对象创建出补丁,描述改变的内容,将这个补丁用来更新DOM。该方法的核心在于walk递归树,该方法将比较后的差异节点放到补丁包中,具体递归树核心逻辑请看下方walk递归树小节。

function diff(oldTree, newTree) {
    let patches = {};
    let index = 0; // 默认先比较树的第一层
    // 递归树  比较后的节点放到补丁包中
    walk(oldTree, newTree, index, patches);
    return patches;
}

这里我们经常会遇到这样的问题
当我们在react 或者vue中对数组遍历并返回多个节点是通常都要设置不同的key,为什么一定要这样做呢
举个删除dom的例子就明白了

  1. 把所有的虚拟dom想像成在一个数组中,当我们删除一个节点,那么它后面的节点就会往前靠
    在这里插入图片描述

  2. DOM Diff这是后会对之前的dom和现在的dom做比较(从前往后比较,当对比到被删除的节点处时,会发现后面的dom节点与之前的不一样了(出现这种情况是删除一个节点后后面的节点都往前靠了,所以对比的之前的结果都不一样)那么后面的都会被一一对比后更替)

这就是为什么我们在遍历时一定要设置key而且key不能为index因为他们默认就是用的index,所以设置成index会出现问题。因此我们的key必须是唯一的

优缺点

优点

  1. 小修改无需频繁更新DOM,框架的diff算法会自动比较,分析出需要
  2. 更新的节点,按需更新更新数据不会造成频繁的回流与重绘
  3. 表达力更强,数据更新更加方便保存的是js对象,具备跨平台能力

缺点
虚拟DOM同样也有缺点,首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值