当前位置: 首页 > news >正文

React和Vue3 的 Diff 算法有什么区别

React 和 Vue 3 的 Diff 算法都有相似的目标,即在组件状态或属性变化时高效地更新 DOM,但它们在实现细节上有所不同。以下是 React 和 Vue 3 的 Diff 算法的主要区别:

React 的 Diff 算法

1. 同层比较

React 使用的是同层比较策略,即只比较同一层级的节点,而不跨层级比较。这样可以显著减少比较的复杂度。

2. 基于 key 的 Diff

React 鼓励使用 key 属性来标识列表中的每个元素。key 是 Diff 算法的核心,用来确定节点的身份。如果节点的 key 发生变化,React 会认为这是一个新的节点,从而重新创建。

3. 递归比对子节点

React 对每个节点进行深度优先遍历,递归比较每个节点及其子节点。如果节点类型相同,则继续比较属性和子节点;如果不同,则直接替换。

4. 批量更新

React 使用批量更新(Batch Updates)策略,即在一个事件循环内收集所有的状态更新,并在下一次渲染周期统一处理。这种方式可以减少浏览器的重排(reflow)和重绘(repaint),从而提升性能。

Vue 3 的 Diff 算法

1. 同层比较

和 React 一样,Vue 3 也使用同层比较策略,只比较同一层级的节点。

2. 基于 key 的 Diff

Vue 3 也使用 key 属性来标识列表中的每个元素。如果没有 key,Vue 会使用节点的顺序进行比较,这可能导致性能下降。

3. 预比较优化

Vue 3 在 Diff 算法中引入了一些预比较优化,例如最长递增子序列(LIS)优化,用来减少节点移动次数。

4. 就地更新

Vue 采用就地更新(In-place Updates)策略,即在每次状态变化时,立即进行对应的 DOM 更新。Vue 通过一个响应式系统来追踪状态的变化,并在状态变化时自动更新对应的 DOM。

具体比较

React 的 Diff 算法示例

function diff(oldTree, newTree) {const patches = {};walk(oldTree, newTree, 0, patches);return patches;
}function walk(oldNode, newNode, index, patches) {const currentPatch = [];if (!newNode) {currentPatch.push({ type: 'REMOVE', index });} else if (typeof oldNode === 'string' && typeof newNode === 'string') {if (oldNode !== newNode) {currentPatch.push({ type: 'TEXT', text: newNode });}} else if (oldNode.type === newNode.type) {const attrPatch = diffAttributes(oldNode.props, newNode.props);if (Object.keys(attrPatch).length > 0) {currentPatch.push({ type: 'ATTR', attrs: attrPatch });}diffChildren(oldNode.children, newNode.children, patches);} else {currentPatch.push({ type: 'REPLACE', node: newNode });}if (currentPatch.length > 0) {patches[index] = currentPatch;}
}function diffAttributes(oldAttrs, newAttrs) {const patch = {};for (let key in oldAttrs) {if (oldAttrs[key] !== newAttrs[key]) {patch[key] = newAttrs[key];}}for (let key in newAttrs) {if (!oldAttrs.hasOwnProperty(key)) {patch[key] = newAttrs[key];}}return patch;
}function diffChildren(oldChildren, newChildren, patches) {const max = Math.max(oldChildren.length, newChildren.length);for (let i = 0; i < max; i++) {walk(oldChildren[i], newChildren[i], ++index, patches);}
}

Vue 3 的 Diff 算法示例

function patch(oldVNode, newVNode, container) {if (!oldVNode) {// 挂载mount(newVNode, container);} else {// 更新patchNode(oldVNode, newVNode);}
}function patchNode(oldVNode, newVNode) {if (oldVNode.type !== newVNode.type) {// 替换不同类型的节点const newEl = createElement(newVNode);oldVNode.el.parentNode.replaceChild(newEl, oldVNode.el);} else {const el = (newVNode.el = oldVNode.el);// 更新属性patchProps(el, oldVNode.props, newVNode.props);// 更新子节点patchChildren(oldVNode, newVNode, el);}
}function patchChildren(oldVNode, newVNode, container) {const oldChildren = oldVNode.children;const newChildren = newVNode.children;if (typeof newChildren === 'string') {container.textContent = newChildren;} else {// 比较新旧子节点const oldLen = oldChildren.length;const newLen = newChildren.length;const commonLen = Math.min(oldLen, newLen);for (let i = 0; i < commonLen; i++) {patch(oldChildren[i], newChildren[i], container);}if (newLen > oldLen) {// 挂载新节点mountChildren(newChildren.slice(oldLen), container);} else if (newLen < oldLen) {// 移除多余节点unmountChildren(oldChildren.slice(newLen));}}
}function patchProps(el, oldProps, newProps) {for (let key in newProps) {el.setAttribute(key, newProps[key]);}for (let key in oldProps) {if (!newProps.hasOwnProperty(key)) {el.removeAttribute(key);}}
}function mountChildren(children, container) {children.forEach(child => {mount(child, container);});
}function unmountChildren(children) {children.forEach(child => {child.el.parentNode.removeChild(child.el);});
}

主要区别

  1. 同层比较:React 和 Vue 3 都使用同层比较策略,只比较同一层级的节点。
  2. 基于 key 的 Diff:React 和 Vue 3 都使用 key 属性来标识列表中的每个元素,确保高效的 Diff 过程。
  3. 预比较优化:Vue 3 在 Diff 算法中引入了预比较优化,例如最长递增子序列(LIS)优化,用来减少节点移动次数。
  4. 递归处理:React 通过深度优先遍历递归处理每个节点及其子节点,Vue 3 也采用类似的策略,但在具体实现上有所不同。

这两个框架的 Diff 算法都是为了在状态或属性变化时高效地更新 DOM,但它们在具体实现细节上有一些不同,主要体现在优化策略和处理方式上。

相关文章:

React和Vue3 的 Diff 算法有什么区别

React 和 Vue 3 的 Diff 算法都有相似的目标&#xff0c;即在组件状态或属性变化时高效地更新 DOM&#xff0c;但它们在实现细节上有所不同。以下是 React 和 Vue 3 的 Diff 算法的主要区别&#xff1a; React 的 Diff 算法 1. 同层比较 React 使用的是同层比较策略&#xf…...

【vulhub靶场之rsync关】

一、使用nmap模块查看该ip地址有没有Rsync未授权访问漏洞 nmap -p 873 --script rsync-list-modules 加IP地址 查看到是有漏洞的模块的 二、使用rsync命令连接并读取文件 查看src目录里面的信息。 三、对系统中的敏感文件进行下载——/etc/passwd 执行命令&#xff1a; rsy…...

全球7大高质量海外代理IP对比大全

随着国内市场逐渐饱和&#xff0c;越来越多朋友私信我说打算开拓海外市场这片蓝海了&#xff01;海外代理IP作为解决这些需求的有效工具&#xff0c;帮助跨境企业或团队进行社媒管理、电商运营、市场调研、抓取数据、广告验证等等业务。但是&#xff0c;市场上提供的代理IP服务…...

对于原型链的理解

1.同一个构造函数的多个实例之间 无法共享属性&#xff08;创建多个实例的时候会造成资源浪费&#xff09; function Cat(name, color) {this.name name;this.color color;this.meow function () {console.log(miao);}; }var cat1 new Cat(LH, White); var cat2 new Cat(…...

Web开发:Vue中的事件小结

一、全选按钮checkbox <template><div id"checkboxs"><label><input id"selectAll" type"checkbox" v-model"selectAllChecked" change"selectAllItems">全部</label><label v-for"…...

基于Springboot的运行时动态可调的定时任务

配置类 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;Configuration public class TaskSchedulerConfig {Bean(destroyMe…...

linux perf

perf是Linux性能分析工具的集合&#xff0c;它提供了丰富的命令来收集和分析程序运行时的性能数据。perf能够报告CPU使用率、缓存命中率、分支预测成功率等多种硬件级别的事件&#xff0c;同时也支持软件级别的事件&#xff0c;如页面错误、任务切换等。perf是理解程序性能瓶颈…...

Linux--网络层IP

IP协议 IP协议&#xff0c;全称Internet Protocol&#xff08;互联网协议&#xff09;&#xff0c;是TCP/IP协议族中的核心协议之一&#xff0c;用于在互联网络上进行数据的传输。IP协议的主要功能是确保数据从一个网络节点&#xff08;如计算机、服务器、路由器等&#xff09…...

浅谈vite之import.meta

一. 解析 开发者使用一个模块时&#xff0c;有时需要知道模板本身的一些信息&#xff08;比如模块的路径&#xff09;。现在有一个提案&#xff0c;为 import 命令添加了一个元属性 import.meta&#xff0c;返回当前模块的元信息。 import.meta只能在模块内部使用&#xff0c;如…...

【Pytorch实用教程】Pytorch中nn.Sequential的用法

nn.Sequential 是 PyTorch 中用于构建神经网络的一种容器类,它可以按顺序封装多个子模块(层),并依次将输入数据传递给这些子模块。这样可以简化模型的定义,使得代码更加简洁和易读。 文章目录 基本用法方法一:直接传递子模块方法二:使用 `OrderedDict`动态构建模型优点注…...

Shopify被封?Shopify店铺开店到防封全面指南

Shopify&#xff0c;作为独立电商建站领域的佼佼者&#xff0c;其SaaS模式简化了建站流程&#xff0c;无需编程背景即可创建线上店铺&#xff0c;吸引了众多商家的目光。本文将详细讲解Shopify店铺从注册、运营到防封的每一个关键环节&#xff0c;为商家提供一站式指导&#xf…...

11. 盛最多水的容器

一题目&#xff1a; 二&#xff1a;代码&#xff1a; class Solution { public:int maxArea(vector<int>& height) {int l0;int rheight.size()-1;int ans0;while(l<r){int a(r-l)*min(height[l],height[r]);ansmax(ans,a);if(height[l]<height[r]) l;else r-…...

react如何父子组件传参

在React中&#xff0c;父子组件之间的传参主要通过props&#xff08;属性&#xff09;来实现。子组件通过props接收来自父组件的数据&#xff0c;而父组件则可以通过在子组件标签上设置属性&#xff08;即props&#xff09;来传递数据。下面是一个简单的例子来说明这个过程。 …...

【C++】二维数组 数组名

二维数组名用途 1、查看所占内存空间 2、查看二维数组首地址 针对第一种用途&#xff0c;还可以计算数组有多少行、多少列、多少元素 针对第二种用途&#xff0c;数组元素、行数、列数都是连续的&#xff0c;且相差地址是有规律的 下面是一个实例 #include<iostream&g…...

【蘑菇书EasyRL】强化学习,笔记整理

【蘑菇书EasyRL】强化学习&#xff0c;笔记整理 1.笔记整理1.1 学习和决策代码框架 2. 遇到的buggym 环境&#xff0c;新版本python无法使用env_specs envs.registry.all() 报错 蘑菇书的教程地址&#xff1a; https://datawhalechina.github.io/easy-rl/#/chapter1/chapter1?…...

尚硅谷谷粒商城项目笔记——三、安装docker【电脑CPU:AMD】

三、安装docker 注意&#xff1a; 因为电脑是AMD芯片&#xff0c;自己知识储备不够&#xff0c;无法保证和课程中用到的环境一样&#xff0c;所以环境都是自己根据适应硬件软件环境重新配置的&#xff0c;这里的虚拟机使用的是VMware。 首先关闭防火墙和安全策略 systemctl…...

【8-9月份唯一机械电气计算机主题的IEEE会议】第七届机电一体化与计算机技术工程国际学术会议(MCTE 2024,8月23-25)

由广东博士创新发展促进会、输变电装备技术全国重点实验室联合主办&#xff0c;重庆大学电气工程学院、AEIC学术交流中心协办的第七届机电一体化与计算机技术工程国际学术会议&#xff08;MCTE 2024&#xff09;将于2024年8月23-25日在中国广州隆重举行。 大会诚挚邀请您投递相…...

YOLOv8改进 | 主干网络 | 简单而优雅且有效的VanillaNet 【华为诺亚方舟】

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有80+篇内容,内含各种Head检测头、损失函数Loss、…...

Tomcat高可用集群(实例详解)

一.环境准备 虚拟机的版本&#xff1a;VMware-workstation-full-15.5.6-16341506.exe系统镜像版本&#xff1a;CentOS-6.10-x86_64-bin-DVD1.iso&#xff0c;全新安装&#xff0c;桌面版&#xff0c;可上网系统内存大小&#xff1a;1GB系统硬盘大小&#xff1a;20GB连接工具版…...

搭建自己的金融数据源和量化分析平台(五):更新两市退市股票信息

在前面的股票列表设计中&#xff0c;我们有一个list_status字段&#xff0c;可能的值为L上市 D退市 P暂停上市。 由于股票可能会被退市&#xff0c;因此需要该字段来维护上市状态。 深市爬虫&#xff1a; # 读取深交所最新退市股票列表 def get_delisted_stock_list():cache_f…...

GPLT L3-042 ‘污染大亨’暴力DFS只拿1分?聊聊竞赛中‘优化剪枝’的思维起点与常见误区

从暴力DFS到优化剪枝&#xff1a;竞赛选手的算法思维跃迁指南 在程序设计竞赛中&#xff0c;我们常常会遇到这样的困境&#xff1a;面对一道看似只能暴力解决的题目&#xff0c;提交后却只得到可怜的1分。这就像原文作者在GPLT L3-042"污染大亨"题中的遭遇——一个简…...

轻型民用无人机安全操控指南:法规解读与实践应用

1. 轻型民用无人机法规基础解读 第一次接触无人机时&#xff0c;我和很多新手一样兴奋地想要马上起飞&#xff0c;直到在公园被保安拦下才知道需要遵守飞行规则。现在每次看到新手飞友准备"黑飞"&#xff0c;我都会主动提醒他们先了解法规。目前我国对轻型民用无人机…...

纽约州校园数据泄露激增背景下的安全治理与技术防御研究

摘要 2026 年 4 月 6 日&#xff0c;databreaches.net发布报道显示&#xff0c;2025 年纽约州校园数据安全事件同比大幅上升72%&#xff0c;其中长岛地区报告数量达44 起&#xff0c;揭示美国 K-12 教育机构在数据安全防护、账号权限管理、威胁监测与应急响应等方面存在系统性短…...

基于贝叶斯优化的稀疏高斯过程回归(BO-SGPR)多输入单输出回归模型【MATLAB】

基于贝叶斯优化的稀疏高斯过程回归&#xff08;BO-SGPR&#xff09;多输入单输出回归模型【MATLAB】 在处理复杂的非线性回归、小样本学习以及带有不确定性量化的预测任务时&#xff0c;高斯过程回归&#xff08;Gaussian Process Regression, GPR&#xff09; 因其强大的理论基…...

OpenClaw如何做好记忆持久化的 · 六、经济学与可扩展性——记忆的代价

六、经济学与可扩展性——记忆的代价⏱ 30 秒速览 | 中度使用&#xff08;日均 50 次对话&#xff09;纯记忆附加成本&#xff1a;~$5/月&#xff08;Claude Sonnet&#xff09;/ ~$1/月&#xff08;GPT-4o-mini&#xff09;。72% 花在记忆注入&#xff0c;24% 花在自动提取&am…...

Abaqus GUI界面中文乱码终极解决方案(含插件兼容指南)

1. Abaqus中文乱码问题全解析 第一次打开Abaqus发现菜单栏全是"口口口"的时候&#xff0c;我差点以为软件装坏了。这种中文乱码问题在工程仿真领域特别常见&#xff0c;尤其是使用中文操作系统的用户。经过多次实践&#xff0c;我发现根本原因是Abaqus默认的locale设…...

IOFILE结构体的介绍与House of orange媚

认识Pass层级结构 Pass范围从上到下一共分为5个层级&#xff1a; 模块层级&#xff1a;单个.ll或.bc文件 调用图层级&#xff1a;函数调用的关系。 函数层级&#xff1a;单个函数。 基本块层级&#xff1a;单个代码块。例如C语言中{}括起来的最小代码。 指令层级&#xff1a;单…...

自动驾驶控制 - 基于运动学模型的LQR算法路径跟踪仿真

自动驾驶控制-基于运动学模型的LQR算法路径跟踪仿真matlab和simulink联合仿真&#xff0c;运动学模型实现的lqr横向控制&#xff0c;可以跟踪双移线&#xff0c;五次多项式&#xff0c;以及其他各种自定义路径。 效果如图&#xff0c;几乎0误差&#xff0c;双移线路径误差在0.0…...

从原理到调参:一文搞懂带权重交叉熵损失函数在目标检测中的应用与优化

从原理到调参&#xff1a;一文搞懂带权重交叉熵损失函数在目标检测中的应用与优化 当你在训练一个目标检测模型时&#xff0c;是否遇到过这样的困境&#xff1a;模型对常见物体的识别准确率很高&#xff0c;但对那些出现频率较低的物体却总是视而不见&#xff1f;这种"选择…...

电解除湿器ROSAHL (电解质膜)的工作原理是什么?电解除湿器推荐?

ROSAHL电解除湿器的核心是固态聚合物电解质&#xff08;SPE&#xff09;膜技术&#xff0c;这是一种通过电化学反应实现除湿的创新方法&#xff0c;它的工作原理可以用"三步走"来概括&#xff1a;① 电解捕获&#xff1a;在3V直流电作用下&#xff0c;除湿器内侧的水…...