转载:diff算法 - v-for中的key值作用 - 掘金
diff算法
diff算法就是用JavaScript来表示一个dom树的结构,然后用这个dom去构建一个真实的dom插入到文档中,当状态变更的时候,重新构造一个dom树,比较新旧dom树,记录两个dom树的差异,然后更新差异部分。
虚拟dom
.vue文件中的template里写的标签, 都是模板, 都要被vue处理成虚拟DOM对象, 才会渲染显示到真实DOM页面上
虚拟dom只有主要的几个属性,速度更快
以后vue数据更新
- 生成新的虚拟DOM结构
- 和旧的虚拟DOM结构对比
- 利用diff算法, 找不不同, 只更新变化的部分(重绘/回流)到页面 - 也叫打补丁
好处1: 提高了更新DOM的性能(不用把页面全删除重新渲染)
好处2: 虚拟DOM只包含必要的属性(没有真实DOM上百个属性)
总结: 虚拟DOM保存在内存中, 只记录dom关键信息, 配合diff算法提高DOM更新的性能
diff算法的新旧对比
情况1: 根元素变了, 删除重建
情况2: 根元素没变, 属性改变, 元素复用, 更新属性
diff算法-key
根元素没变, 子元素没变, 元素内容改变
1. 无key - 就地更新
v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key
来提供一个排序提示
2. 有key-key为索引
还是就地更新,因为新旧虚拟DOM对比, key存在就复用此标签更新内容, 如果不存在就直接建立一个新的
3. 有key-key为id
key的值只能是唯一不重复的, 字符串或数值。v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key
来提供一个排序提示
总结:
vue是如何提高更新性能的?
- 采用虚拟DOM+diff算法提高更新性能
虚拟DOM是什么?
- 本质是保存dom关键信息的JS对象
diff算法如何比较新旧虚拟DOM?
- 根元素改变 – 删除当前DOM树重新建
- 根元素未变, 属性改变 – 更新属性
- 根元素未变, 子元素/内容改变 - 更新内容
- 无key – 就地更新 / 有key – 按key比较