赞
踩
我们都知道的一件事,就是vue和react框架,核心算法都是diff算法,啥叫diff算法可能有一部分人都是没有深究的,今天梳理一下vue和react的diff算法,也说一下有啥区别
什么叫虚拟dom,就是原本我们在页面上展示的dom结构叫做dom树,我们把数据和将要渲染的代码模拟dom结构生成的对象类型的数据结构,就叫虚拟dom树,
将真实的DOM的数据抽取出来,以对象的形式模拟树形结构,我们先根据真实DOM生成一颗 virtual DOM ,当 virtual DOM 某个节点的数据改变后会生成一个新的 Vnode ,然后 Vnode 和 oldVnode 作对比,发现有不一样的地方就直接修改在真实的DOM上,然后使 oldVnode 的值为 Vnode 。
遍历循环比较,这里我就不画图了,简单的说一下,很重要,首先肯定要理解啥叫diff算法,然后才知道vue和react的diff算法是怎么做的优化同级比较,不做跨级比较
新旧列表的两端对比oldStartNode与新列表的头一个节点newStartNode对比oldEndNode与新列表的最后一个节点newEndNode对比oldStartNode与新列表的最后一个节点newEndNode对比oldEndNode与新列表的头一个节点newStartNode对比oldStartNode与新列表的头一个节点newStartNode对比时key相同,那么旧列表的头指针oldStartIndex与新列表的头指针newStartIndex同时向后移动一位,dom不动oldEndNode与新列表的最后一个节点newEndNode对比时key相同,那么旧列表的尾指针oldEndIndex与新列表的尾指针newEndIndex同时向前移动一位,dom不动oldStartNode与新列表的最后一个节点newEndNode对比时key相同,那么旧列表的头指针oldStartIndex向后移动一位,新列表的尾指针newEndIndex向前移动一位,插入到旧列表的newEndNode所对应的dom后边newStartNode对比时key相同,那么旧列表的尾指针oldEndIndex向前移动一位,新列表的头指针newStartIndex向后移动一位,插入到就列表的oldStartIndex所对应的dom前边undefined,这是相当重要的一步,由于咱们已经作了节点的移动了因此咱们不须要进行再次的对比了,最后咱们将头指针newStartIndex向后移一位
因为对比规则非常的重要,这点完全决定了是否能可以真正理解vue的diff算法,所以这里我解释一下具体的对比规则,对比上图我们看到,刚进来就要进行最基础的1234步骤对比,我们分两种情况来看接下来的走向
- 第一种是
四种里边有对比成功的:那么我们就会把对比成功的那个旧节点和新节点的指针都向临近的元素进行一个移动,这里具体是什么意思呢,就是说当前旧节点和新节点已经有了相匹配的,我们进行了真实dom的操作之后,我们需要做的就是移动指针,这四个指针是依旧要进行比较的- 第二种就是没匹配到这四种情况,那么就需要我们拿当前的newStartNode指针指到的节点去跟旧节点列表中的所有节点去遍历比较,比较之后找到了匹配的旧节点的话,就把当前找到的旧节点所对应的dom移动到开头,然后把找到的旧节点设置成
undefined,如果找不到,我们就在当前旧节点列表的oldStartIndex处创建新dom且插入,而且把newStartNode指针向后移动,设置成undefined的原因就是我们已经把当前找到的这个旧节点所对应的dom进行了处理,那么随着我们指针进行移动接着对比的时候,就要跳过已经被处理过的节点了- 总体来说就是我们拿新节点列表的首位和末尾去和旧列表的首位末尾依次对比,如果对比上了,就进行操作,如果没有对比上,我们就遍历处理新节点,直到对比上了或者处理好了新节点列表的首位,我们就会接着按照原逻辑去处理,比直接拿着一个个去遍历,多了一个首尾两端对比,避免了第一个和最后一个对上需要遍历所有的尴尬境地

总结:
- react-diff: 遍历法对比
- vue-diff: 双端对比
- 总体来讲vue的diff算法更佳,总体规律就是找到新节点所对应的旧节点列表中的节点,而后给真实的对应的dom移动到正确的位置
- vue3.0的diff算法还没有梳理过,以后可以在说vue3.0其他东西的时候带上,一些更改的地方该了解的还是要了解的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。