当前位置: 首页 > 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 ( 具…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...