虚拟dom和diff算法

虚拟dom就是用js模拟dom树对象,由一个一个虚拟节点vnode,虚拟节点又能嵌套虚拟节点,这样层层嵌套形成一个树结构,把它称为个虚拟dom树,在模板编译阶段。

为什么操作虚拟dom比操作真实dom快?

    1.减少DOM的操作。虚拟dom可以将多次操作合并为一次操作,比如你添加1000个节点,原生可能会一个一个添加。vue中可能创建一个数组,往里面放1000个文本,最后一次性的放到界面上。减少dom操作的次数
    2.减少dom操作的范围。虚拟dom可以借助dom diff算法,把多余的操作省略。页面上有990个标签,现在有1000个标签想替换原来的,原生的话会把1000个标签全部进行渲染。用了diff算法后会去比较变化的部分,只把变化的部分渲染到真实DOM上。。
    3.虚拟dom本质上是一个js对象,v8引擎编译js代码速度非常快。

diff算法?
         通过patch函数进行两个虚拟节点的比较,diff算法计算出最小化的变化,再操作真实的DOM,不变的不会重新渲染。
diff算法再对比两个节点的时候分为两种:
一种暴力拆除旧的,插入新的

​ 1.不是同一个虚拟节点,父节点不是原来的节点。直接暴力拆掉,不管新的父节点里面的孩子是否相同,直接删,把新的节点全部换 上去。原来是ul中四个li,每个li分别是ABCD。新的是ol中有四个li,每个li分别是ABCD。
​ 2.只进行同层比较,不会进行跨层比较。即使是同一片虚拟节点,但是跨层了,精细化不diff你,暴力删除,插入新的。一个div下一层是四个span,一个div下一层是一个p,这个p的下一层是相同的四个span。diff比较原来的一层是四个span,现在的一层是一个p,不好意思,不在进行下面的比较,直接拆除,换上新的。
如何定义同一个虚拟节点?选择器相同,key相同。
key是服务于最小量更新的,用来表明在更改前后它们是同一个dom节点。
eg: 给a,b,c,d前面插入e
如果不加key,diff算法不会智能的判断你是在哪添加。会在最后增加一个节点,把文字的顺序改了。原来a的内容变成e,b的内容变成a。增加了一个节点,改变5个文字,全部重新渲染一遍。
​ 加了key,就告诉它,他还是原来的那个a,还是原来的那个b,还是原来的那个c,还是原来的那个d。再给前面加e就真的是在前面加e。只是增加了一个节点。
​ 加了key里面的顺序乱了,也只是把之间的节点树的顺序打乱就行,不会拆掉原来的节点。

一种是进行精细化比较

前提是同一个虚拟节点。

新节点有text属性,直接将el.innerHTML换成新节点的text,不管旧的有没有text属性

新节点有children属性,旧节点没有,清空旧节点的text,将新节点的children添加到dom中

新节点有children,旧节点也有children

有四命中规则,和剩余项的处理

新前与旧前

新后与旧后

新后与旧前 ③命中了,就把旧前指向的节点移动到旧后后面 ABCDE EDCBA

新前与旧后 ④命中了,就把旧后指向的节点移动到旧前前面 ABCDE ECM

如果旧的先遍历完说明要把新节点中剩余的节点按顺序添加上去 AB ABCD

如果新的先遍历完说明要把旧节点中剩余的节点删除 ABCD ABC

如果在一轮命中规则后还没有命中,就在旧的节点里面循环找新前指向的节点,如果找到,打上undefined标签(undefined就是在虚拟dom已经死了,在真实dom上已经被插上去了),并把节点移动到旧前之前,新前指针移动。如果没找到,把新前指向的节点插入到旧前之前,新前指针向下移动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值