用v-for来解释diff的算法原理 及 diff算法与虚拟dom的关系解释

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_36146776/article/details/90173407

我的个人理解

  • diff算法:
    从上往下逐层进行比较,给每个节点生成标识符用在同级进行对比,:如果标识符相同,则继续比较此节点的下一级,如果子节点都相同则复用;如果子级有不同,则对此子节点进行判断,
    节点中如果出现了新的标识符,则新增;如果旧节点的标识符在新中没有出现,则删除;如果标识符相同,内容不同,则进行替换。
  • diff算法与虚拟dom关系:
    提到虚拟dom,则会联想到真实DOM,真实DOM用jquery或者document操作,每个算法语句都会检索文档,然后进行改变,非常消耗性能,虚拟dom的出现就是对其性能的优化,通过diff算法,进行新旧结果的比较,然后一次性更新所有dom的操作。
    简而言之:通过diff算法得到diff算法结果数据表,得到了需要操作哪些记录表,然后用js的DOM fragment来操作dom,即统一计算出所有变化后统一更新一次DOM,

vue和react的虚拟dom算法大致相同,其核心是基于两个简单的假设
diff的操作处理方法:对操作前后的dom树同一层的节点进行对比,一层一层对比。

在这里插入图片描述

举例说明
在B和C之间插入F
Diff算法默认执行起来是这样的:即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
在这里插入图片描述
解决:我们使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
在这里插入图片描述
旧节点key和新节点key值相同的地方abcde可以“就地复用”,不用重新计算,因此大大提高了效率。

react中的解释:无论何时调用setState组件,react会将其标记为脏。在时间循环结束时,react会查看所有的脏组件并重新呈现他们。
这种批处理意味着在事件循环期间,只有一次更新DOM。此属性是构建高性能应用程序的关键
https://calendar.perfplanet.com/2013/diff/

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by="$index"
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性:
https://cn.vuejs.org/v2/api/#key
key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。

猜你喜欢

转载自blog.csdn.net/sinat_36146776/article/details/90173407