Vue的diff算法详解 原创

前端老实人
发布于 2022-1-19 16:56
浏览
0收藏

Vue 中的diff算法?

概念:diff算法是一种优化方法,用于比较两个模块之间的差异。修补(更新)的过程差异称为修补。

为什么diff算法存在于 Vue 和 react 框架中?

我们都知道渲染真实DOM的开销是巨大的,这类似于性能优化中重绘和重新排列的含义。回到正题,有时我们在页面中修改一些数据。 如果直接渲染到真正的DOM导致了整数的重绘和重新排列,我们可以直接修改数据吗? 映射到真正的DOM并进行最小的重绘重排,这里您应该对使用diff算法的原因有一个简单的概念 ,为什么使用diff算法

虚拟 DOM 和真实 DOM 之间的区别

综上所述,虚拟DOM就是提取真实的DOM数据,并以对象的形式模拟树结构。diff算法也与虚拟 DOM 进行了比较。

代码理解

<div>
    <p> JS Daily Question</p>
</div>

// Converting to VNode is similar to the following

const Vnode = {
    tag: 'div',
    children: [
        {tag:'p', text:'JS Daily Question'}
    ]
};

差异如何比较?

要发布的源代码太多。如果您有兴趣,可以查看 https://github.com/vuejs/vue/

简单地说,新旧虚拟 doms 之间的比较,如果有差异,新的 doms 将占上风,然后插入到真正的 doms 中,重新渲染

特征

仅点对点比较,不进行跨级别比较
比较后一种情况

  • if (oldVnode === vnode)他们的报价是一致的,可以认为是不变的。
  • if(oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text)将调用需要修改的文本节点的比较。Node.textContent = vnode.text
  • if( oldCh && ch && oldCh !== ch )两个节点都有子节点,而且它们不同,所以我们称它们为函数比较子节点,这是 diff 的核心。updateChildren
  • else if (ch)只有新节点才具有子节点。调用,旧的DOM节点已被引用。该函数将子节点添加到旧 DOM 节点。createEle(vnode)vnode.elcreateEle
  • else if (oldCh)新节点没有子节点,旧节点有子节点,因此可以直接删除旧节点。

key的作用

设置key和不设置key的区别:

没有key,newCh和oldCh只会比较头部和端部的末端。设置键时,除了头部两端和端部之间的比较外,它们还将从key生成对象。查找匹配的节点,以便为节点设置key可以更有效地DOMoldKeyToIdx

如果我们想在 B 和 C 之间添加 F,默认情况下执行 Diff 算法,如下所示:
Vue的diff算法详解-鸿蒙开发者社区

因此,我们需要使用 key 为每个节点进行唯一标识。diff算法可以正确识别此节点,并找到正确的位置区域以插入新节点。
Vue的diff算法详解-鸿蒙开发者社区
所以一句话,key主要用于高效更新虚拟DOM。此外,关键属性还用于在 vue 中具有相同标签名称的元素的过渡切换。目的也是使 Vue 能够区分它们。否则,Vue 将仅替换其内部属性,而不会触发过渡效果。

总结

尽量不要跨级别修改 DOM
开发组件时,保持稳定的 DOM 结构有助于提高性能
设置键使差异更有效

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2022-1-19 16:56:55修改
收藏
回复
举报
回复
    相关推荐