JS逐日一题:Vue中的diff算法?

20190125

Vue中的diff算法?

观点: diff算法是一种优化手腕,将前后两个模块举行差别对照,修补(更新)差别的历程叫做patch(打补丁)

为何vue,react这些框架中都会有diff算法呢? 我们都晓得衬着实在dom的开支是很大的,这个跟机能优化中的重绘重排意义相似, 回到正题来, 有时候我们修正了页面中的某个数据,假如直接衬着到实在DOM中会引发整棵数的重绘重排, 那末我们能不能只让我们修正的数据映射到实在DOM, 做一个起码化重绘重排呢,说到这里你应当对为何运用diff算法有一个简朴的观点了

virtual DOM和实在DOM的辨别

一句话归纳综合吧,virtual DOM是将实在的DOM的数据抽取出来,以对象的情势模仿树形构造, diff 算法比较的也是virtual DOM

代码明白

<div>
    <p>JS逐日一题</p>
</div>

// 转换成VNode 相似于下面这类

const Vnode = {
    tag: 'div',
    children: [
        { tag: 'p', text: 'JS逐日一题' }
    ]
};
diff 是怎样比较的?

源码太多了,就不贴了, 有兴致的能够本身看看
https://github.com/vuejs/vue/…

简朴的说就是新旧假造dom 的比较,假如有差别就以新的为准,然后再插进去的实在的dom中,从新衬着

特性

  • 只会做同级比较,不做跨级比较
  • 比较后几种状况

    • if (oldVnode === vnode),他们的援用一致,能够认为没有变化。
    • if(oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text),文本节点的比较,须要修正,则会挪用Node.textContent = vnode.text
    • if( oldCh && ch && oldCh !== ch ), 两个节点都有子节点,而且它们不一样,如许我们会挪用updateChildren函数比较子节点,这是diff的中心
    • else if (ch),只要新的节点有子节点,挪用createEle(vnode)vnode.el已援用了老的dom节点,createEle函数会在老dom节点上增加子节点。
    • else if (oldCh),新节点没有子节点,老节点有子节点,直接删除老节点。
key的作用

设置key和不设置key的辨别:
不设key,newCh和oldCh只会举行头尾两头的互相比较,设key后,除了头尾两头的比较外,还会从用key天生的对象oldKeyToIdx中查找婚配的节点,所认为节点设置key能够更高效的应用dom

如我们愿望能够在B和C之间加一个F,Diff算法默许执行起来是如许的:

《JS逐日一题:Vue中的diff算法?》

即把C更新成F,D更新成C,E更新成D,末了再插进去E,是否是很没有效率?

所以我们须要运用key来给每一个节点做一个唯一标识,Diff算法就能够准确的辨认此节点,找到准确的位置区插进去新的节点。

《JS逐日一题:Vue中的diff算法?》
《JS逐日一题:Vue中的diff算法?》
所以一句话,key的作用重要是为了高效的更新假造DOM。别的vue中在运用雷同标署名元素的过渡切换时,也会运用到key属性,其目标也是为了让vue能够辨别它们,不然vue只会替代其内部属性而不会触发过渡结果

总结

  • 只管不要跨层级的修正dom
  • 在开辟组件时,保持稳定的 DOM 构造会有助于机能的提拔
  • 设置key能够让diff更高效

关于JS逐日一题

JS逐日一题能够看成是一个语音答题社区
天天应用碎片时候采纳60秒内的语音情势来完成当天的考题
群主在越日0点推送当天的参考答案

  • 注 毫不仅限于完成当天使命,更多是查漏补缺,进修群内别的同砚优异的答题思绪

点击到场答题

    原文作者:febobo
    原文地址: https://segmentfault.com/a/1190000018330547
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞