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

为何Vue3比Vue2快

Proxy响应式

PatchFlag

  • 编译模板时,动态节点做标记
  • 标记,分为不同的类型,如TEXT PROPS
  • diff算法时,可以区分静态节点,以及不同类型的动态节点
<div>Hello World</div>
<span>{{ msg }}</span>
<span class="msg">闻人放歌</span>
<span id="name">{{ msg }}</span>
<span class="msg-class" :msg="message">{{ msg }}</span>

编译结果:

import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(_Fragment, null, [_createElementVNode("div", null, "Hello World"),_createElementVNode("span", null, _toDisplayString(_ctx.msg), 1 /* TEXT */),_createElementVNode("span", { class: "msg" }, "闻人放歌"),_createElementVNode("span", { id: "name" }, _toDisplayString(_ctx.msg), 1 /* TEXT */),_createElementVNode("span", {class: "msg-class",msg: _ctx.message}, _toDisplayString(_ctx.msg), 9 /* TEXT, PROPS */, ["msg"])], 64 /* STABLE_FRAGMENT */))
}// Check the console for the AST

在这里插入图片描述
静态字段将不再比较,这样diff算法将少比较很多节点。

hoistStatic

  • 将静态节点的定义,提升到父作用域,缓存起来
  • 多个相邻的静态节点,会被合并起来
  • 典型的拿空间换时间的优化策略
//  模板
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>

编译结果:

import { createElementVNode as _createElementVNode, createCommentVNode as _createCommentVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", null, "Hello World", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createElementVNode("div", null, "Hello World", -1 /* HOISTED */)
const _hoisted_3 = /*#__PURE__*/_createElementVNode("div", null, "Hello World", -1 /* HOISTED */)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(_Fragment, null, [_hoisted_1,_hoisted_2,_hoisted_3,_createCommentVNode(" <span>{{ msg }}</span>\n<span class=\"msg\">闻人放歌</span>\n<span id=\"name\">{{ msg }}</span>\n<span class=\"msg-class\" :msg=\"message\">{{ msg }}</span> ")], 64 /* STABLE_FRAGMENT */))
}// Check the console for the AST

还有一个点,如果静态节点数量多,编译会自动合并,如:

<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
import { createElementVNode as _createElementVNode, createCommentVNode as _createCommentVNode, createStaticVNode as _createStaticVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"const _hoisted_1 = /*#__PURE__*/_createStaticVNode("<div>Hello World</div><div>Hello World</div><div>Hello World</div><div>Hello World</div><div>Hello World</div><div>Hello World</div><div>Hello World</div><div>Hello World</div><div>Hello World</div><div>Hello World</div>", 10)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(_Fragment, null, [_hoisted_1,_createCommentVNode(" <span>{{ msg }}</span>\n<span class=\"msg\">闻人放歌</span>\n<span id=\"name\">{{ msg }}</span>\n<span class=\"msg-class\" :msg=\"message\">{{ msg }}</span> ")], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
}// Check the console for the AST

cacheHandler

上代码:

<div @click="clickHandler">Hello World</div>

编译结果:

import { openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock("div", {onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.clickHandler && _ctx.clickHandler(...args)))}, "Hello World"))
}// Check the console for the AST

从编译结果代码可以看出,如果该事件方法已被定义则直接去缓存中的方法,没有则定义。其意义就是缓存事件

SSR优化

编译前:

<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>Hello World</div>
<div>{{ msg }}</div>
<div @click="clickHandler">Hello World</div>
<div class="msg-class">{{ msg }}</div>
<div class="msg-class" :msg="msg">闻人放歌</div>

编译结果:

import { mergeProps as _mergeProps } from "vue"
import { ssrRenderAttrs as _ssrRenderAttrs, ssrInterpolate as _ssrInterpolate } from "vue/server-renderer"export function ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) {const _cssVars = { style: { color: _ctx.color }}_push(`<!--[--><div${_ssrRenderAttrs(_cssVars)}>Hello World</div><div${_ssrRenderAttrs(_cssVars)}>Hello World</div><div${_ssrRenderAttrs(_cssVars)}>Hello World</div><div${_ssrRenderAttrs(_cssVars)}>Hello World</div><div${_ssrRenderAttrs(_cssVars)}>Hello World</div><div${_ssrRenderAttrs(_cssVars)}>Hello World</div><div${_ssrRenderAttrs(_cssVars)}>${_ssrInterpolate(_ctx.msg)}</div><div${_ssrRenderAttrs(_cssVars)}>Hello World</div><div${_ssrRenderAttrs(_mergeProps({ class: "msg-class" }, _cssVars))}>${_ssrInterpolate(_ctx.msg)}</div><div${_ssrRenderAttrs(_mergeProps({class: "msg-class",msg: _ctx.msg}, _cssVars))}>闻人放歌</div><!--]-->`)
}// Check the console for the AST
  • 静态节点直接输出,绕过了vdom
  • 动态节点,还是需要动态渲染

tree-shaking

观察两者编译结果区别:

<div v-if="msg">Hello World</div>
<input v-model="msg">
// 编译结果
import { openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, vModelText as _vModelText, createElementVNode as _createElementVNode, withDirectives as _withDirectives, Fragment as _Fragment } from "vue"export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createElementBlock(_Fragment, null, [(_ctx.msg)? (_openBlock(), _createElementBlock("div", { key: 0 }, "Hello World")): _createCommentVNode("v-if", true),_withDirectives(_createElementVNode("input", {"onUpdate:modelValue": $event => ((_ctx.msg) = $event)}, null, 8 /* PROPS */, ["onUpdate:modelValue"]), [[_vModelText, _ctx.msg]])], 64 /* STABLE_FRAGMENT */))
}// Check the console for the AST

<div v-if="msg">Hello World</div>// 编译结果
import { openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode } from "vue"export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_ctx.msg)? (_openBlock(), _createElementBlock("div", { key: 0 }, "Hello World")): _createCommentVNode("v-if", true)
}// Check the console for the AST

编译时,根据不同的情况,引入不同的API

相关文章:

为何Vue3比Vue2快

Proxy响应式 PatchFlag 编译模板时&#xff0c;动态节点做标记标记&#xff0c;分为不同的类型&#xff0c;如TEXT PROPSdiff算法时&#xff0c;可以区分静态节点&#xff0c;以及不同类型的动态节点 <div>Hello World</div> <span>{{ msg }}</span>…...

人工智能与社交变革:探索Facebook如何领导智能化社交平台

在过去十年中&#xff0c;人工智能&#xff08;AI&#xff09;技术迅猛发展&#xff0c;彻底改变了我们与数字世界互动的方式。Facebook作为全球最大的社交媒体平台之一&#xff0c;充分利用AI技术&#xff0c;不断推动社交平台的智能化&#xff0c;提升用户体验。本文将深入探…...

八股文之java基础

jdk9中对字符串进行了一个什么优化&#xff1f; jdk9之前 字符串的拼接通常都是使用进行拼接 但是的实现我们是基于stringbuilder进行的 这个过程通常比较低效 包含了创建stringbuilder对象 通过append方法去将stringbuilder对象进行拼接 最后使用tostring方法去转换成最终的…...

深度挖掘行情接口:股票市场中的关键金融数据API接口解析

在股票市场里&#xff0c;存在若干常见的股票行情数据接口&#xff0c;每一种接口皆具备独特的功能与用途。以下为一些常见的金融数据 API 接口&#xff0c;其涵盖了广泛的金融数据内容&#xff0c;其中就包含股票行情数据&#xff1a; 实时行情接口 实时行情接口&#xff1a…...

逆向破解 对汇编的 简单思考

逆向破解汇编非常之简单 只是一些反逆向技术非常让人难受 但网络里都有方法破解 申请变量 &#xff1a; int a 0; 00007FF645D617FB mov dword ptr [a],0 char b b; 00007FF645D61802 mov byte ptr [b],62h double c 0.345; 00007FF645D61…...

搜维尔科技:人机交互学术应用概览

人机交互学术应用概览 搜维尔科技&#xff1a;人机交互学术应用概览...

植物遗传转化相关介绍【卡梅德生物】

植物的遗传转化是指以植物器官、组织、细胞或原生质体作为受体&#xff0c;应用重组DNA技术&#xff0c;将外源基因导入植物基因组&#xff0c;以获得转基因植物的技术。目前应用最普遍的植物基因的遗传转化方法主要有农杆菌介导法和DNA直接转入法。 一&#xff0e;植物遗传转化…...

0711springNews新闻系统管理 实现多级评论

0611springmvc新闻系统管理-CSDN博客 0711springNews新闻系统管理项目包 实现多级评论-CSDN博客 数据库字段 需要添加父节点id&#xff0c;通过该字段实现父评论和子评论的关联关系。 对象属性 实现链表&#xff0c;通过一个父评论可以找到它对应的所有子孙评论。 业务层 实现…...

如何在Ubuntu上安装并启动SSH服务(Windows连接)

在日常的开发和管理工作中&#xff0c;通过SSH&#xff08;Secure Shell&#xff09;连接到远程服务器是一个非常常见的需求。如果你在尝试通过SSH连接到你的Ubuntu系统时遇到了问题&#xff0c;可能是因为SSH服务未安装或未正确配置。本文将介绍如何在Ubuntu上安装并启动SSH服…...

docker build时的网络问题

docker build时无法yum安装包&#xff0c;因为无法访问外网&#xff0c;无法ping通外网。 解决办法&#xff1a; systemctl stop NetworkManager.service firewall-cmd --permanent --zonetrusted --change-interfacedocker0 systemctl start NetworkManager.service systemct…...

Vue的安全性:防范XSS攻击与安全最佳实践

引言 随着Web应用的普及,前端安全问题日益受到重视。Vue作为当下流行的前端框架,其安全性也成为开发者关注的焦点。跨站脚本攻击(XSS)是常见的Web安全漏洞之一,本文将讨论如何在使用Vue时防范XSS攻击,并分享其他Vue中的安全最佳实践。 什么是XSS攻击? XSS攻击是一种将…...

ARM架构(一)—— ARMV8V9基础概念

目录 1.ARMCore的时间线2.ARM术语小结2.1 A64和arrch642.2ARM架构现在的5个系列2.3 微架构2.4 PE2.5 Banked2.6 ARM文档术语2.7 IMPLEMENTATION DEFINFD 和 DEPRECATED2.8 EL1t和EL1h 3 ARMv7的软件架构4 安全状态切换模型4.1 Secure state和Non-secure state介绍 5 Interproce…...

如何使用Python进行数据分析

Python是一种广泛应用于数据科学和机器学习领域的编程语言。本文将介绍如何使用Python进行数据分析&#xff0c;包括Python在数据分析中的应用场景、常用库和工具&#xff0c;以及实际案例分析。 一、Python在数据分析中的应用场景 数据清洗&#xff1a;处理缺失值、异常值&a…...

Python学习笔记40:游戏篇之外星人入侵(一)

前言 入门知识已经学完&#xff0c;常用标准库也了解了,pygame入门知识也学了&#xff0c;那么开始尝试小游戏的开发。 当然这个小游戏属于比较简单的小游戏&#xff0c;复杂的游戏需要长时间的编写累计开发经验&#xff0c;同时也需要一定的时间才能编写出来。现在的话还是嫩…...

R的数据集读取和利用,如何高效地直接复制黏贴数据到R

​​​​​​R语言自带了许多内部数据集,这些数据集不仅为初学者提供了丰富的练习资源,还为研究人员和数据分析师提供了方便的数据测试和模型验证工具。在这篇文章中,我们将详细探讨如何读取和使用数据集。 一、认识数据集 1、数据和数据集 数据(Data)是指以某种形式表示…...

@JsonProperty 踩坑

JsonProperty 在fastjson 和 hutooljson 中是不会生效的。 在 fastjson 中&#xff0c;对应的注解是 JSONField。如果你正在使用 fastjson 进行 JSON 的序列化和反序列化&#xff0c;并且想要改变字段的 JSON 属性名&#xff0c;你应该使用 JSONField 注解&#xff0c;而不是 …...

业务架构、数据架构、应用架构和技术架构分析

一文看懂&#xff1a;什么是业务架构、数据架构、应用架构和技术架构 TOGAF&#xff08;开放集团架构框架&#xff09;是企业广泛应用的架构设计和管理利器。其核心在于四大架构领域&#xff1a;业务、数据、应用和技术&#xff0c;助力组织高效运作。TOGAF&#xff0c;让架构设…...

android studio中svn的使用

第一步&#xff0c;建立一个项目。 第二步&#xff0c;share project。 第三步&#xff0c;选择存放的位置&#xff0c;然后添加提交信息&#xff0c;最后点击share。这样就可以在svn上面看到一个空的项目名称。 第四步&#xff0c;看到文件变成了绿色&#xff0c;点击commit图…...

敏捷CSM认证:精通敏捷Scum估算方法,高效完成项目!

咱们做项目的时候可能都遇到过这种情况&#xff1a;项目一开始信心满满&#xff0c;觉得 deadline 稳了。结果呢&#xff1f;各种意外状况频出&#xff0c;时间好像怎么都不够用了&#xff0c;最后项目只能无奈延期&#xff0c;整个团队都像霜打的茄子。 说到底&#xff0c;还…...

三、建造者模式

文章目录 1 基本介绍2 案例2.1 Car 类2.2 CarBuilder 抽象类2.3 EconomyCarBuilder 类2.4 LuxuryCarBuilder 类2.5 CarDirector 类2.6 测试程序2.7 测试结果2.8 总结 3 各角色之间的关系3.1 角色3.1.1 Product ( 产品 )3.1.2 Builder ( 抽象建造者 )3.1.3 ConcreteBuilder ( 具…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

C++ 设计模式 《小明的奶茶加料风波》

&#x1f468;‍&#x1f393; 模式名称&#xff1a;装饰器模式&#xff08;Decorator Pattern&#xff09; &#x1f466; 小明最近上线了校园奶茶配送功能&#xff0c;业务火爆&#xff0c;大家都在加料&#xff1a; 有的同学要加波霸 &#x1f7e4;&#xff0c;有的要加椰果…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...