React 与 Vue 虚拟 DOM 实现原理深度对比:从理论到实践
在现代前端开发中,React 和 Vue 作为最流行的两大框架,都采用了虚拟 DOM(Virtual DOM) 技术来优化渲染性能。虚拟 DOM 的核心思想是通过 JavaScript 对象模拟真实 DOM,减少直接操作 DOM 的开销,从而提高页面渲染效率。
尽管 React 和 Vue 都使用虚拟 DOM,但它们的实现方式、优化策略和适用场景存在显著差异。本文将深入探讨两者的异同,并结合代码示例分析其底层机制,帮助开发者更好地理解并选择合适的框架。
1. 虚拟 DOM 的基本概念
1.1 什么是虚拟 DOM?
虚拟 DOM 是一个轻量级的 JavaScript 对象,用于描述真实 DOM 的结构。例如:
// 虚拟 DOM 示例
const vdom = {type: 'div',props: { className: 'container' },children: [{ type: 'h1', props: {}, children: 'Hello World' },{ type: 'p', props: {}, children: 'This is a virtual DOM.' }]
};
1.2 虚拟 DOM 的工作流程
-
生成虚拟 DOM:组件渲染时,框架生成新的虚拟 DOM 树。
-
Diff 对比:比较新旧虚拟 DOM 树的差异(Diff 算法)。
-
Patch 更新:仅将变化的部分应用到真实 DOM(避免全量渲染)。
2. React 的虚拟 DOM 实现
2.1 JSX 与虚拟 DOM 生成
React 使用 JSX 描述 UI,JSX 会被 Babel 转换为 React.createElement
调用,生成虚拟 DOM:
// JSX 代码
const element = <div className="container">Hello React</div>;// 编译后
const element = React.createElement('div',{ className: 'container' },'Hello React'
);
2.2 Diff 算法(React Reconciliation)
React 采用 双端 Diff 算法(React 16+ 引入 Fiber 架构),核心优化策略:
-
同级比较:只比较同一层级的节点,减少递归深度。
-
Key 优化:列表更新时,
key
帮助 React 识别哪些元素可以复用。
示例:列表 Diff
// 没有 key 时,React 可能低效更新
<ul>{items.map(item => <li>{item}</li>)}
</ul>// 使用 key 优化
<ul>{items.map(item => <li key={item.id}>{item.text}</li>)}
</ul>
2.3 更新机制
React 默认采用 全量 Diff,即父组件更新会导致所有子组件重新渲染,除非手动优化:
-
React.memo
(函数组件) -
shouldComponentUpdate
(类组件)
// 使用 React.memo 避免不必要的渲染
const MemoComponent = React.memo(({ data }) => {return <div>{data}</div>;
});
2.4 Fiber 架构
React 16 引入 Fiber,将 Diff 过程拆分为可中断的小任务,避免长时间阻塞主线程。
3. Vue 的虚拟 DOM 实现
3.1 模板编译与虚拟 DOM
Vue 使用 模板语法(或 JSX),在编译阶段优化虚拟 DOM 生成:
<!-- Vue 模板 -->
<template><div class="container"><h1>Hello Vue</h1><p>{{ message }}</p></div>
</template>
编译后,Vue 会生成 render
函数:
// 编译后的 render 函数
function render() {return h('div', { class: 'container' }, [h('h1', null, 'Hello Vue'),h('p', null, this.message)]);
}
3.2 Diff 算法优化
Vue 的 Diff 算法在 React 的基础上进一步优化:
-
静态节点提升:编译时标记静态节点,Diff 时直接跳过。
-
动态节点标记(patchFlag):仅对比动态变化的节点。
示例:静态节点优化
<template><div><h1>Static Title</h1> <!-- 静态节点,仅首次渲染 --><p>{{ dynamicText }}</p> <!-- 动态节点,Diff 时对比 --></div>
</template>
3.3 响应式驱动的更新
Vue 的虚拟 DOM 与 响应式系统 深度集成,数据变化时自动触发更新:
export default {data() {return { count: 0 };},methods: {increment() {this.count++; // 自动触发虚拟 DOM 更新}}
};
3.4 细粒度更新
Vue 3 的 composition API
进一步优化更新粒度:
import { ref } from 'vue';export default {setup() {const count = ref(0);return { count }; // 只有 count 变化时,相关组件才更新}
};
4. React vs Vue 虚拟 DOM 对比
4.1 虚拟 DOM 生成方式
框架 | 描述方式 | 编译优化 |
---|---|---|
React | JSX(全量生成) | 无优化 |
Vue | 模板(静态分析) | 静态节点提升、动态标记 |
4.2 Diff 算法
框架 | Diff 策略 | 优化手段 |
---|---|---|
React | 双端 Diff + Fiber 调度 | 依赖 key 手动优化 |
Vue | 双端 Diff + 静态标记 | 自动跳过静态节点 |
4.3 更新粒度
框架 | 更新方式 | 优化方法 |
---|---|---|
React | 组件级(全量 Diff) | React.memo 、useMemo |
Vue | 组件级(响应式驱动) | 自动依赖追踪 |
4.4 适用场景
-
React:适合需要精细控制渲染逻辑的大型应用(如复杂交互、状态管理)。
-
Vue:适合快速开发、追求开箱即用优化的项目(如企业后台、电商页面)。
5. 性能实测对比
5.1 初始渲染速度
-
Vue 通常更快(静态节点提升减少 Diff 计算)。
-
React 需要手动优化(如
React.memo
)。
5.2 列表更新效率
// React:依赖 key 优化
{items.map(item => <Item key={item.id} data={item} />)}// Vue:自动优化,但仍推荐 key
<template v-for="item in items" :key="item.id"><Item :data="item" />
</template>
5.3 高频更新场景
-
Vue 的响应式系统通常更高效(自动追踪依赖)。
-
React 需要结合
useMemo
、useCallback
优化。
结论
对比维度 | React | Vue |
---|---|---|
虚拟 DOM 生成 | JSX(全量) | 模板(静态优化) |
Diff 算法 | 双端 Diff + Fiber | 双端 Diff + 静态标记 |
更新机制 | 手动优化(memo) | 自动依赖追踪 |
适用场景 | 复杂交互、状态管理 | 快速开发、企业应用 |
最终建议:
-
如果你喜欢灵活控制渲染逻辑,选择 React。
-
如果你希望减少手动优化,选择 Vue。
相关文章:
React 与 Vue 虚拟 DOM 实现原理深度对比:从理论到实践
在现代前端开发中,React 和 Vue 作为最流行的两大框架,都采用了虚拟 DOM(Virtual DOM) 技术来优化渲染性能。虚拟 DOM 的核心思想是通过 JavaScript 对象模拟真实 DOM,减少直接操作 DOM 的开销,从而提高页面…...
结合五层网络结构讲一下用户在浏览器输入一个网址并按下回车后到底发生了什么?
文章目录 实际应用第一步:用户在浏览器输入 www.baidu.com 并按下回车1. 浏览器触发域名解析(DNS查询) 第二步:DNS请求的逐层封装与传输1. 应用层(DNS协议)2. 传输层(UDP协议)3. 网络…...
关于Code_流苏:商务合作、产品开发、计算机科普、自媒体运营,一起见证科技与艺术的交融!
Code_流苏 🌿 名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 🌟 欢迎来到Code_流苏的CSDN主页 —— 与我一起&…...
Webpack模块打包工具
1. 认识webpack的基本用法步骤创建项目->下载webpack webpack-cli -> npm init -y -> package.json的scripts中配置webpack默认打包入口:src/index.js默认打包出口: dist/main.js2. 认识webpack.config.js的基本配置loader -> 打包css,less…...
crossOriginLoading使用说明
1. 说明 此配置用于控制 Webpack 动态加载的代码块(chunk)(例如代码分割或懒加载的模块)在跨域(不同域名)加载时的行为。它通过为动态生成的 <script>标签添加 crossorigin 属性,确保符合…...
Linux系统性能调优技巧分享
在数字化时代,Linux 系统以其开源、稳定、高效的特性,成为服务器、云计算、物联网等领域的核心支撑。然而,随着业务规模的扩大和负载的增加,系统性能问题逐渐凸显。掌握 Linux 系统性能调优技巧,不仅能提升系统运行效率,还能降低运维成本。下面从多个方面介绍实用的性能调…...
在Windows11中配置Git+SSH环境,本此实践使用Gitee(码云),方法同样适用于其它绝大部分Git服务
1.下载并安装Git 进入官网下载 Git - Downloading Package 选择下载Standalone Installer安装包,看自己电脑是64-bit还是32-bit(一般都是64-bit) 双击安装包进行安装,Next 这里可以自定义安装路径 这里可以勾选添加桌面快捷方式…...
【软考-架构】14、软件可靠性基础
✨资料&文章更新✨ GitHub地址:https://github.com/tyronczt/system_architect 文章目录 软件可靠性基本概念软件可靠性建模软件可靠性管理软件可靠性设计N版本程序设计恢复块设计(动态冗余)双机容错技术、集群技术负载均衡软件可靠性测试…...
怎样理解ceph?
Ceph 是一个开源的、高度可扩展的 分布式存储系统,设计用于提供高性能、高可靠性的对象存储(Object)、块存储(Block)和文件存储(File)服务。它的核心思想是通过去中心化的架构和智能的数据分布策…...
《AI大模型趣味实战》智能Agent和MCP协议的应用实例:搭建一个能阅读DOC文件并实时显示润色改写过程的Python Flask应用
智能Agent和MCP协议的应用实例:搭建一个能阅读DOC文件并实时显示润色改写过程的Python Flask应用 引言 随着人工智能技术的飞速发展,智能Agent与模型上下文协议(MCP)的应用场景越来越广泛。本报告将详细介绍如何基于Python Flask框架构建一个智能应用&…...
Pygame字体与UI:打造游戏菜单和HUD界面
Pygame字体与UI:打造游戏菜单和HUD界面 在现代游戏中,用户界面(UI)是玩家与游戏互动的重要桥梁。一个精心设计的UI不仅能够提升游戏的视觉效果,还能增强玩家的游戏体验。Pygame作为一个强大的游戏开发库,提供了丰富的工具和方法来创建和管理UI元素。本文将详细介绍如何使…...
游戏引擎学习第246天:将 Worker 上下文移到主线程创建
回顾并为今天的工作做准备 关于GPU驱动bug的问题,目前本地机器上没有复现。如果有问题,昨天的测试就应该已经暴露出来了。当前演示的是游戏的过场动画,运行正常,使用的是硬件渲染。 之前使用软件渲染时没有遇到太多问题ÿ…...
系统设计(2)—Redis—消息队列—数据库—熔限降
Redis 缓存设计 在高并发系统中,缓存是提升性能、减轻后端负载的杀手锏。Redis 作为内存级的高性能缓存数据库,被广泛应用于各类系统设计中。利用 Redis,将热点数据存储在内存中,可以加速读写并大幅降低对后端关系型数据库的直接…...
第十六届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学 A 组
比赛还没有开始,竟然忘记写using namespace std; //debug半天没看明白 (平时cv多了 然后就是忘记那个编译参数,(好惨的开局 编译参数-stdc11 以下都是赛时所写代码,赛时无聊时把思路都打上去了(除了倒数第二题&#…...
HiSpark Studio如何使用Trae(Marscode)插件
引言 我现在非常喜欢使用编程辅助插件,用的最多的是Trae(以前叫Marscode)。以前华为的DevEco Device Tools是基于VSCode的,直接使用官方的插件市场就可以安装了。现在海思提供了自己的HiSpark Studio,比原来的Device …...
Netmiko连接池与长连接优化
背景与原理 在网络自动化中,频繁创建和断开 SSH 连接会带来以下问题: 性能损耗:每次连接需经历 TCP 握手、SSH 协商、用户认证等流程,耗时约 1~3 秒。资源浪费:设备端可能限制并发连接数,频繁连接易触发阈…...
10:00面试,10:08就出来了,面试问的问题太。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%,这…...
从基础到实战的量化交易全流程学习:1.2 金融市场基础
从基础到实战的量化交易全流程学习:1.2 金融市场基础 在量化交易领域,扎实的金融市场基础是策略开发与风险控制的核心支撑。本文将从交易品种、市场机制、监管合规三方面展开,结合市场特性、真实数据案例及实践要点进行系统化解析,…...
游戏状态管理:用Pygame实现场景切换与暂停功能
游戏状态管理:用Pygame实现场景切换与暂停功能 在开发游戏时,管理游戏的不同状态(如主菜单、游戏进行中、暂停等)是非常重要的。这不仅有助于提升玩家的游戏体验,还能使代码结构更加清晰。本文将通过一个简单的示例,展示如何使用Pygame库来实现游戏中的场景切换和暂停功…...
数据资产价值及其实现路径-简答题回顾
1. 简述数据资产的定义及其特征。 答案:数据资产是指企业或组织所拥有的、具有经济价值的数据资源。它具有以下特征:可复制性(数据可以多次使用)、价值潜力(数据经过处理、分析可以创造经济价值)、流动性&…...
Docker化HBase排错实录:从Master hflush启动失败到Snappy算法未支持解决
前言 在容器化时代,使用 Docker 部署像 HBase 这样复杂的分布式系统也比较方便。社区也提供了许多方便的 HBase Docker 镜像,没有找到官方的 apache的,但有包含许多大数据工具的 harisekhon/hbase 或用于学习目的的 bigdatauniversity/hbase…...
端到端自动驾驶的数据规模化定律
25年4月来自Nvidia、多伦多大学、NYU和斯坦福大学的论文“Data Scaling Laws for End-to-End Autonomous Driving”。 自动驾驶汽车 (AV) 栈传统上依赖于分解方法,使用单独的模块处理感知、预测和规划。然而,这种设计在模块间通信期间会引入信息丢失&am…...
桌面端开发技术栈选型:开启高效开发之旅
在数字化浪潮中,桌面端应用依然占据重要地位,而选择合适的技术栈是打造优质桌面端应用的关键一步。以下是多种主流桌面端开发技术栈的介绍与对比,希望能为大家提供有价值的参考。 基于 Web 技术的跨平台框架 • Electron: • 特…...
C++模拟Java C#的 finally
在 Java 和 C# 中,finally 是一个与异常处理(try-catch)配合使用的关键字,用于确保一段代码无论是否发生异常都会被执行。它通常用于释放资源(如文件句柄、数据库连接、锁等),避免内存泄漏或状态…...
Spring Boot安装指南
🔖 Spring Boot安装指南 🌱 Spring Boot支持两种使用方式: 1️⃣ 可作为常规Java开发工具使用 2️⃣ 可作为命令行工具安装 ⚠️ 安装前提: 📌 系统需安装 Java SDK 17 或更高版本 🔍 建议先运行检查命令…...
zephyr架构下Bluetooth advertising接口
目录 概述 1 函数接口 2 主要函数介绍 2.1 bt_le_adv_start函数 2.1.1 函数功能介绍 2.1.2 典型使用示例 2.1.3 广播间隔 2.1.4 注意事项 2.2 bt_le_adv_stop 函数 2.2.1 函数功能 2.2.2 使用方法介绍 2.2.3 实际应用示例 2.2.4 关键注意事项 2.2.5 常见问题解决 …...
Oracle官宣 MySQL+APEX+AI三认证限时免费
1 MySQL8 OCP 考试代码 1Z0-908 免费时间:2025年4月20日至7月31日 https://education.oracle.com/mysql-promo 2 APEX云开发专家 考试代码 1Z0-771 免费时间:2025年5月15日截止! https://mylearn.oracle.com/ou/learning-path/become…...
深入理解N皇后问题:从DFS到对角线优化
N皇后问题是一个经典的算法问题,要求在NN的棋盘上放置N个皇后,使得它们互不攻击。本文将全面解析该问题的解法,特别聚焦于DFS算法和对角线优化的数学原理。 问题描述 在NN的国际象棋棋盘上放置N个皇后,要求: 任意两个…...
1软考系统架构设计师:第一章系统架构概述 - 超简记忆要点、知识体系全解、考点深度解析、真题训练附答案及解析
超简记忆要点 一、考试大纲 目标:架构设计能力(需求→架构)能力:技术/方法/行业科目:综合(选择)、案例(问答)、论文(论述) 二、架构核心 定义…...
MuJoCo 关节角速度记录与可视化,监控机械臂运动状态
视频讲解: MuJoCo 关节角速度记录与可视化,监控机械臂运动状态 代码仓库:GitHub - LitchiCheng/mujoco-learning 关节空间的轨迹优化,实际上是对于角速度起到加减速规划的控制,故一般来说具有该效果的速度变化会显得丝…...
如何打包python程序为可执行文件
将 Python 程序打包为可执行文件是一个常见需求,尤其是在希望将应用程序分享给不具备 Python 环境的用户时。以下是使用 PyInstaller 工具将 Python 程序打包为可执行文件的步骤。 步骤 1:安装 PyInstaller 如果您还没有安装 PyInstaller,请…...
产销协同是什么?产销协同流程有哪些?
目录 一、产销协同是什么 1.从市场需求的角度来看 2.企业内部运营的角度来看 3.从供应链的角度来看 二、实现产销协同的八大步骤 1. 市场需求预测 2. 销售计划制定 3. 生产能力评估 4. 生产计划制定 5. 库存管理 6. 信息共享与沟通 7. 订单执行与跟踪 8. 绩效评估…...
SQL 查询进阶:WHERE 子句与连接查询详解
SQL(Structured Query Language)是管理关系型数据库的核心语言,熟练掌握其查询功能对于数据处理至关重要。本文将深入探讨 SQL 中的两个关键概念:WHERE 子句和连接查询。我们将详细讲解 WHERE 子句中的模糊查询、IS NULL、IS NOT …...
【计算机视觉】CV实战项目- DFace: 基于深度学习的高性能人脸识别
图:MTCNN的三阶段网络结构(P-Net、R-Net、O-Net) DFace深度解析:基于深度学习的高性能人脸识别 深度解析DFace:基于PyTorch的实时人脸检测与识别系统技术背景与项目概述核心功能与特点实战部署指南环境准备硬件要求软…...
基于Docker、Kubernetes和Jenkins的百节点部署架构图及信息流描述
以下是基于Docker、Kubernetes和Jenkins的百节点部署架构图及信息流描述,使用文本和Mermaid语法表示: 架构图(Mermaid语法) #mermaid-svg-WWCAqL1oWjvRywVJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-WWCAq…...
百度搜索AI开放计划:让应用连接精准流量的秘诀
引言 在人工智能技术深刻改变各行各业的今天,每天都有许多AI应用诞生。然而无论是开发者还是用户依然会感到自己的应用鲜有人使用或是需求没有被充分满足。这种情况正说明了为什么我们需要SEO流量,而一个能够与AI应用直接相关的SEO平台更是呼之欲出。百度…...
Redis数据结构SDS,IntSet,Dict
1.字符串:SDS SDS的底层是C语言编写的构建的一种简单动态字符串 简称SDS,是redis比较常见的数据结构。 由于以下几种缺点,Redis并没有直接采用C语言的字符串。 1.获取长度需要计算 2.非二进制安全 :中间不能有 \0,…...
leetcode201.数字范围按位与
找到公共前缀部分,然后后面的部分全0 class Solution {public int rangeBitwiseAnd(int left, int right) {int offset 0;while (left ! right) {offset;left left >> 1;right right >> 1;}return right << offset;} }...
云服务器 —— 公有 IP 与 私有 IP
云服务器的 公有 IP 和 私有 IP 在网络架构中扮演不同的角色,具体用途和区别如下: 目录 1. 公有 IP(Public IP) 作用: 特点: 示例场景: 2. 私有 IP(Private IP) 作用…...
北斗导航 | Transformer增强BiLSTM网络的GNSS伪距观测量误差探测
在GNSS(全球导航卫星系统)定位中,伪距观测量的误差直接影响定位精度。结合Transformer和LSTM的优势,可以设计一种混合模型以提升误差探测能力。以下是具体的技术实现方案: 1. 模型架构设计 1.1 输入特征设计 原始GNSS观测数据: 伪距观测值(C/A码、P码)、载波相位、多普…...
0803分页_加载更多-网络ajax请求2-react-仿低代码平台项目
文章目录 1 分页1.1 url与分页参数1.2 分页组件与url1.3 列表页引用分页组件 2 加载更多2.1 状态2.2 触发时机2.3 加载数据2.4优化 结语 1 分页 1.1 url与分页参数 查询问卷列表接口,添加分页参数: page:当前页码(第几页&#…...
React 与 Vue 的区别:你会选择哪个框架呢
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…...
Jmeter如何取JDBC request响应参数作为下一个接口的值?
1、 功能参数说明 Variable Name:数据库连接池的名字,需要与JDBC Connection Configuration的Variable Name Bound Pool名字保持一致 Query:填写的sql语句未尾不要加“;” Parameter valus:参数值,对查询条件进行参数化 Paramete…...
【C++】14.容器适配器 | stack | queue | 仿函数 | priority_queue
1. 容器适配器 什么是适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设 计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。 在C中,容器适配器(Container Adapters&…...
论文阅读:2025 arxiv Aligning to What? Limits to RLHF Based Alignment
Aligning to What? Limits to RLHF Based Alignment https://arxiv.org/pdf/2503.09025 https://www.doubao.com/chat/3871529075012866 速览 这篇论文主要探讨了强化学习从人类反馈(RLHF)在对齐大型语言模型(LLMs)时的局限性…...
利用Arcgis自己绘制shp文件
1.选择自己想要创建的shp文件的位置 我是直接创建在连接文件夹中 2.右键-新建-shp 3.设置名称、要素类型、空间参考 4、点击创建要素 5、右侧选择图层、创建面 6、开始绘制,双击任意位置结束绘制 之后可以改一下shp文件的名字...
路由器重分发(OSPF+静态路由)
路由器重分发(OSPF静态路由) 静态路由充当不了翻译官 OSPF路由 OSPF路由需要宣告自己的ip, Router(config)#router ospf 1 Router(config-router)#network 10.10.10.0 0.0.0.255 area 0还要帮静态路由的也宣告一下 Router(config)#ip route…...
KTT入门
Kinetic tournament tree 简称 KTT 下文中全部简写。 KTT 用于解决类以下问题: 已知 N N N 条一次函数,求解一段区间内函数最大值。支持修改操作可以修改 x i x_i xi 或者 b i b_i bi 的值。具体做法: 我们考虑线段树来维护一个类似 Δ \Delta Δ 的东西,我们令当…...
WPF 上位机开发模板
WPF 上位机开发模板 WPF上位机开发模板,集成了基础操作菜单、海康视觉实时图像界面、串口通讯、网口通讯、主流PLC通讯、数据存储、图片存储、参数配置、权限管理、第三方webapi接口接入、数据追溯与查询等功能。 一、项目结构 WpfSupervisor/ ├── Models/ …...
理想星环OS选择NuttX作为MCU侧OS的核心原因分析
文章目录 引言一、POSIX兼容性:降低汽车软件迁移成本二、轻量级与模块化:适配MCU资源约束三、硬实时性能:保障车辆控制确定性四、多芯片适配:加速车企供应链灵活性五、安全与可靠性:构建纵深防御体系六、社区与生态&am…...