简要了解
- Diff 算法目的就是找出新旧虚拟dom差异,最小化更新视图;即本质就是比较两个JS对象的差异;
- 并不是页面上所有的更新都需要Diff算法。
在了解Diff算法之前,我们首先需要了解一下什么是虚拟DOM。
虚拟DOM
虚拟DOM是表示真实DOM的JS对象
这是一段真实DOM:
<div class="container"><p class="item">CSDN:浅墨_东</p><strong class="intro">一个前端小白菜</strong>
</div>
它对应的虚拟DOM是下列的一个JS对象:
let Vnode = {tagName: "div",props: {class: "container",},children: [{tagName: "p",props: {'class': "item",},text:'CSDN:浅墨_东'},{tagName: "strong",props: {'class': "item",},text:'一个前端小白菜'},],};
里面包含字段有:标签名、标签属性、子标签名称属性、文本节点。
我们在了解虚拟DOM之后,就可以来了解Diff算法
Diff算法
如果我们修改了上面真实DOM的文本内容:
<div class="container"><p class="item">CSDN:浅墨_东</p><strong class="intro">专注分享前端干货</strong>
</div>
就会生成一个新的虚拟DOM:
let Vnode = {tagName: "div",props: {class: "container",},children: [{tagName: "p",props: {'class': "item",},text:'CSDN:浅墨_东'},{tagName: "strong",props: {'class': "item",},text:'专注分享前端干货'},],};
如果能快速找到新旧JS对象之间的差异,就可以最小化的更新视图,那么就产生了 Diff 算法;Diff算法的目的就是找出差异,最小化更新视图。
原理图
updateChildren 详解
一段真实DOM如果变成右侧DOM结构
内部进行同级比对,减少比对次数 ,最大化提高比对性能
在统计比对的时候,采用的是首尾指针法
不管是新旧虚拟节点,都有首尾两个元素,对应的是start和end,首先旧虚拟节点的start和新虚拟节点start做比对
如果没有比对成功,旧虚拟节点start和新虚拟节点end做比对 如果依旧没有比对成功,旧虚拟节点end和新虚拟节点start做比对
如果还没有比对成功,旧虚拟节点end和新虚拟节点end做比对 比对规则按照以下顺序进行比较:
如果旧虚拟节点start和新虚拟节点end比对成功,则真实dom中对应的元素要移动到第4个位置去。(根据新虚拟节点位置)
比对成功,oldS向右侧移动,newE向左侧移动,接着开始第二轮不对
依次进行 .....
最后比对完,发现新虚拟节点有新的元素,我们把新元素添加到真实dom中
✨原创不易,还希望各位大佬支持一下!
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!