diff算法 --陈辉 想你了

101 阅读2分钟

虚拟dom

diff算法 -- diff算法的对象是虚拟dom,更新真实dom是diff算法的结果。

为什么使用虚拟dom

1. DOM操作代价昂贵,可维护性差

2. 虚拟DOM轻量,对虚拟DOM操作快

3. diff算法是找出本次DOM需要更新的节点,不更新的节点进行dom就地复用,可以减少浏览器页面的重绘。

diff算法原理

1. patch原理

patch函数接收6个参数: oldVnode vnode hydrating removeOnly parentElm refElm

patch逻辑:

1.if vnode不存在 oldVnode存在 调用 invokeDestroyHook 销毁节点

2.if oldVnode不存在 vnode存在 调用createElm来创建节点

3. 当vnode 和 oldVnode 都存在 同一个节点 调用patchVnode。 当vnode 和 oldVnode 不是同一个节点,如果oldVnode是真实的dom节点或者hydrating为true,用hydrating函数将虚拟dom和真实dom进行映射,然后将oldVnode设置为对应的虚拟dom,找到oldVnode的父节点,根据vnode创建真实dom插入到父节点中oldVnode.elm的位置。

patchVnode逻辑:

1. 如果oldVnode === vnode 不需要做任何事情

2. 如果oldVnode和vnode都是静态节点 且有相同的key 当vnode是克隆节点或是v-once指令控制的节点,把oldVnode.elm和oldVnode.child都复制到vnode

3. 如果vnode不是文本节点或注释节点 如果oldVnode和vnode都有子节点 节点不一致 调用updateChildren。如果oldVnode只有子节点,则将节点都删除。如果只有vnode有子节点,则创建子节点。如果oldVnode和vnode都没有子节点,但是oldVnode是文本节点或注释节点,就把vnode.elm文本设置成空字符串

<p> 4. 如果vnode是文本节点或注释节点,但vnode.text !==oldVnode.text,只需要更新vnode.elm文本内容就可以了。 </p>


3. diff算法是找出本次DOM需要更新的节点,不更新的节点进行dom就地复用,可以减少浏览器页面的重绘。
</p>