Vue虚拟DOM与diff算法

就地复用

Vue会尽可能的就地(同层级,同位置),对比虚拟dom,复用旧dom结构,进行差异化更新。

虚拟DOM

真实DOM

  • HTML渲染出来的DOM树
  • 每个标签都是树的节点
  • 每个节点拥有非常多的属性 由于真实DOM的属性过多,导致对比差异会消耗过多的性能,且有很多无需遍历对比的属性,这样效率很低。

虚拟DOM

本质是JS对象,保存渲染真实DOM时的必要属性。

<template>
<div id="app">
  <h1 class="title">标题</h1>
</div>
</template>

<script>
 const virtualDOM = {
   type:'div',
   attributes:[{id:'app'}],
   children:[{
     type:'h1',
     attributes:[{class:"title"}],
     text:'标题'
   }]
 }
</script>
渲染过程
  1. template渲染成虚拟DOM
  2. 根据虚拟DOM渲染成真实的DOM
数据发生更新
  1. 重新生成一份新的虚拟DOM
  2. 对比新的虚拟DOM和旧的虚拟DOM,找到不同的地方
  3. 最后统一更新真实的DOM
虚拟DOM的作用

可以在内存中创建虚拟DOM,快速比较变化的部分, 然后给真实DOM打补丁(更新)

虚拟DOM总结

虚拟DOM相比真实DOM只保留了渲染时必要的属性,可以更高效地对比DOM新旧差异,进行差异化更新。

diff算法

虚拟DOM内部的比对过程称为diff算法

策略一

先同层级根元素比较,如果根元素变化,那么不考虑复用,整个dom树删除重建

策略二

对比同级兄弟元素时,默认按照下标进行对比复用。如果数组顺序没有发生改变,性能是高效的。

如果数组的顺序发生了变化,性能并不高

策略三

同级兄弟元素,在设置了key后,会让相同key的元素进行对比。

key必须是字符串或者数字,且必须唯一

(尽量不用遍历的索引作为key,参考策略二中数组的顺序发生变化)

总结

  • 设置了key在DOM更新时会按照相同的key进行新旧元素比较(不设置则默认为索引)
  • 目的:提高更新时的性能
  • key必须是字符串或者数字,且必须唯一

已发布

分类

来自

标签:

评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注