Vue2、Vue3 和 React 中 Diff 算法的区别

1、总结版 

DOM diff 本质上就是在数据响应式的场景下,降低了用户对 DOM 的直接操作。

像 Vue2、Vue3 和 React 底层都有用到 DOM diff,它们的相同点呢,就都是同级比对,复杂度差不多;

那不同点呢,一个是指针移动的方向。比如 React 是从左向右移动的,而 Vue2 是双端 diff, 也就是指针是两边向中间移动的。而 Vue3 在 Vue2 双端 diff 的基础上,加上了最长递增子序列优化算法。

从时间复杂度来说呢,Vue2 应该是比 React 快一倍的,但是 Vue3 在 JS 层,它的复杂度就不是 O(n) 了,而是 O(nlogN) 。

而 Vue3 为什么复杂度更高了呢,因为 Vue3 的核心是为了减少 DOM 的移动,因为在浏览器中 JS 速度是很快的,但是 DOM 的移动是很昂贵的,而且 DOM 渲染速度很慢,很影响性能。

而最长递增子序列这个算法能够让 DOM 最小范围的移动。虽然JS复杂度变高了,但是 DOM 移动次数变少了提高了 DOM 的渲染效率以及性能。所以在数据变化比较大的情况下,比较适合用 Vue3 的选型。

2、分析版

Vue2 双端交叉指针,新老 Vdom 各有2个指针,分别进行头头、尾尾、头尾、尾头优化比较;

Vue3 也是双端快速 diff,新老 Vdom 各有2个指针,只比对头头和尾尾,如果能够匹配上,那就跟2.0是一致的。

如果没有匹配上,就会触发最长递增子序列的算法计算,就是在新的 Vdom 里面寻找依次递增的元素有哪些,找到之后,这些元素它的顺序就是固定的,去寻找不在这些列表里面的元素。与老的Vdom进行比对,再进行移动、删除或者创建;

实际上它的时间复杂度是O(nlog(n)),但是在 Vue2 里面,它的复杂度是 O(n)。那这么来看,3.0的复杂度更高了。那为什么要提高复杂度呢?

因为3.0核心是为了减少 DOM 的移动,因为在浏览器中 DOM 的移动它是非常昂贵的,但是 JS 损失一点也没关系。所以总体来看,损失了 JS 的性能,但是提升了浏览器 DOM 的渲染效率,总体来说是利大于弊的。

3、Vue 3.0 使用的 diff 算法相比 Vue 2.0 中的双端比对有以下优势

① 最长递增子序列算法 

Vue 3.0 的 diff 算法采用了最长递增子序列算法,能够减少不必要的 DOM 操作,提升性能。

② 静态标记

Vue 3.0 中,编译器会对静态节点进行标记,在更新时可以直接跳过这些静态节点,减少 DOM 操作,提升性能。

③ 缓存数组

Vue 3.0 中每次更新时会将新旧 VNode 数组缓存起来,只对数组中不同的 VNode 进行比对,减少比对次数,提升性能。

④ 动态删除操作

Vue 3.0 中,对于动态删除操作,采用了异步队列的方式进行,能够将多个删除操作合并为一个,减少 DOM 操作,提升性能。

总的来说,Vue 3.0 的 diff 算法相比 Vue 2.0 更加高效,能够减少不必要的 DOM 操作,提升应用的性能。

VueReact 都是用于构建用户界面的 JavaScript 库,它们都依赖于高效的虚拟 DOM 来优化性能。尽管这两种框架都是基于虚拟 DOM 的原理来进行渲染更新,但是它们各自采用了不同的 diff 算法来确定哪些元素需要更新以及如何更新。 ### VueDiff 算法 Vuediff 算法基于比较旧版和新版虚拟 DOM 树结构来找出差异,并计算出最小化实际 DOM 更新所需的修改步骤。Vue 使用了一个名为“change detection”的系统来检测数据模型的变化并生成新的虚拟 DOM 表示形式。这个过程涉及到一系列策略和优化措施: 1. **深度优先遍历**:Vue 采用深度优先搜索的方式来遍历虚拟 DOM 树,这样可以确保所有子节点都在其父节点之前得到处理,便于管理更新顺序。 2. **依赖跟踪**:Vue 跟踪每个组件的数据依赖,当某个属性或状态发生改变时,它会找到所有依赖该属性的组件,并只更新必要的部分。 3. **缓存**:对于静态内容,Vue 可以通过缓存来避免不必要的更新操作,提高效率。 4. **虚拟节点合并**:Vue 将相似的虚拟节点合并成一个节点,减少实际 DOM 操作的数量。 5. **DOM 拆分与合并**:Vue 利用浏览器提供的特性,如 CSS 动画、CSS 过渡等,在某些情况下直接利用浏览器的能力来优化渲染流程。 ### ReactDiff 算法 Reactdiff 算法被称为 "Reconciliation"(再协调),它也依赖于比较虚拟 DOM 和实际 DOM 的差异,然后决定如何最小化更改。Reactdiff 算法有几个关键特点: 1. **一次一更新**(Single Update):React 在更新过程倾向于一次性更新整个页面的一部分,而不是逐个更新每个组件。这意味着如果多个组件依赖相同的数据源,React 只需要更新受影响的部分。 2. **JSX 树形表示**:React 使用 JSX 语法将组件声明为树状结构,这有助于清晰地表示组件之间的层次关系,简化了 diff 计算的过程。 3. **批处理**(Batching):React 提供批处理功能,允许在一个特定的时间点(例如:在每次事件循环结束时)执行所有的 DOM 更新,这有助于改善用户体验并减少抖动现象。 4. **最小化变更集**:Reactdiff 算法则专注于识别变化并最小化实际的 DOM 更新操作,比如使用 `shouldComponentUpdate` 或 `getDerivedStateFromProps` 函数来控制组件是否需要更新。 5. **高效缓存**:React 使用缓存机制来记住已渲染的组件状态,以便在数据发生变化时能够快速更新组件,而不需要完全重建整个组件。 ### 相关问题 - VueReact Diff 算法区别? 1. **内存使用**:VueReact 在内存使用方面有何差异?哪种方法更节省资源? 2. **性能优化**:在大型应用VueReactDiff 算法如何影响性能?有哪些最佳实践可以进一步优化性能? 3. **复杂度处理**:对于高度动态的界面,VueReactDiff 算法分别能提供怎样的支持?在遇到复杂状态变化时,两者的处理机制有何异同?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值