「Vue3面试系列」Vue3.0性能提升主要是通过哪几方面体现的?

文章目录
- 一、编译阶段
- diff算法优化
- 静态提升
- 事件监听缓存
- SSR优化
- 二、源码体积
- 三、响应式系统
- 参考文献
一、编译阶段
回顾Vue2,我们知道每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把用到的数据property记录为依赖,当依赖发生改变,触发setter,则会通知watcher,从而使关联的组件重新渲染

试想一下,一个组件结构如下图
<template><div id="content"><p class="text">静态文本</p><p class="text">静态文本</p><p class="text">{{ message }}</p><p class="text">静态文本</p>...<p class="text">静态文本</p></div>
</template>
可以看到,组件内部只有一个动态节点,剩余一堆都是静态节点,所以这里很多 diff 和遍历其实都是不需要的,造成性能浪费
因此,Vue3在编译阶段,做了进一步优化。主要有如下:
- diff算法优化
- 静态提升
- 事件监听缓存
- SSR优化
diff算法优化
vue3在diff算法中相比vue2增加了静态标记
关于这个静态标记,其作用是为了会发生变化的地方添加一个flag标记,下次发生变化的时候直接找该地方进行比较
下图这里,已经标记静态节点的p标签在diff过程中则不会比较,把性能进一步提高

关于静态类型枚举如下
export const enum PatchFlags {TEXT = 1,// 动态的文本节点CLASS = 1 << 1, // 2 动态的 classSTYLE = 1 << 2, // 4 动态的 stylePROPS = 1 << 3, // 8 动态属性,不包括类名和样式FULL_PROPS = 1 << 4, // 16 动态 key,当 key 变化时需要完整的 diff 算法做比较HYDRATE_EVENTS = 1 << 5, // 32 表示带有事件监听器的节点STABLE_FRAGMENT = 1 << 6, // 64 一个不会改变子节点顺序的 FragmentKEYED_FRAGMENT = 1 << 7, // 128 带有 key 属性的 FragmentUNKEYED_FRAGMENT = 1 << 8, // 256 子节点没有 key 的 FragmentNEED_PATCH = 1 << 9, // 512DYNAMIC_SLOTS = 1 << 10, // 动态 soltHOISTED = -1, // 特殊标志是负整数表示永远不会用作 diffBAIL = -2 // 一个特殊的标志,指代差异算法
}
静态提升
Vue3中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用
这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用
<span>你好</span><div>{{ message }}</div>
没有做静态提升之前
export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock(_Fragment, null, [_createVNode("span", null, "你好"),_createVNode("div", null, _toDisplayString(_ctx.message), 1 /* TEXT */)], 64 /* STABLE_FRAGMENT */))
}
做了静态提升之后
const _hoisted_1 = /*#__PURE__*/_createVNode("span", null, "你好", -1 /* HOISTED */)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock(_Fragment, null, [_hoisted_1,_createVNode("div", null, _toDisplayString(_ctx.message), 1 /* TEXT */)], 64 /* STABLE_FRAGMENT */))
}// Check the console for the AST
静态内容_hoisted_1被放置在render 函数外,每次渲染的时候只要取 _hoisted_1 即可
同时 _hoisted_1 被打上了 PatchFlag ,静态标记值为 -1 ,特殊标志是负整数表示永远不会用于 Diff
事件监听缓存
默认情况下绑定事件行为会被视为动态绑定,所以每次都会去追踪它的变化
<div><button @click = 'onClick'>点我</button>
</div>
没开启事件监听器缓存
export const render = /*#__PURE__*/_withId(function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock("div", null, [_createVNode("button", { onClick: _ctx.onClick }, "点我", 8 /* PROPS */, ["onClick"])// PROPS=1<<3,// 8 //动态属性,但不包含类名和样式]))
})
开启事件侦听器缓存后
export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock("div", null, [_createVNode("button", {onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args)))}, "点我")]))
}
上述发现开启了缓存后,没有了静态标记。也就是说下次diff算法的时候直接使用
SSR优化
当静态内容大到一定量级时候,会用createStaticVNode方法在客户端去生成一个static node,这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染
div><div><span>你好</span></div>... // 很多个静态属性<div><span>{{ message }}</span></div>
</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(_mergeProps(_attrs, _cssVars))}><div><span>你好</span>...<div><span>你好</span><div><span>${_ssrInterpolate(_ctx.message)}</span></div></div>`)
}
二、源码体积
相比Vue2,Vue3整体体积变小了,除了移出一些不常用的API,再重要的是Tree shanking
任何一个函数,如ref、reavtived、computed等,仅仅在用到的时候才打包,没用到的模块都被摇掉,打包的整体体积变小
import { computed, defineComponent, ref } from 'vue';
export default defineComponent({setup(props, context) {const age = ref(18)let state = reactive({name: 'test'})const readOnlyAge = computed(() => age.value++) // 19return {age,state,readOnlyAge}}
});
三、响应式系统
vue2中采用 defineProperty来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加getter和setter,实现响应式
vue3采用proxy重写了响应式系统,因为proxy可以对整个对象进行监听,所以不需要深度遍历
- 可以监听动态属性的添加
- 可以监听到数组的索引和数组
length属性 - 可以监听删除属性
关于这两个 API 具体的不同,我们下篇文章会进行一个更加详细的介绍
参考文献
- https://juejin.cn/post/6903171037211557895
相关文章:
「Vue3面试系列」Vue3.0性能提升主要是通过哪几方面体现的?
文章目录 一、编译阶段diff算法优化静态提升事件监听缓存SSR优化 二、源码体积三、响应式系统参考文献 一、编译阶段 回顾Vue2,我们知道每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把用到的数据property记录为依赖,当依赖发…...
网络结构模式
一、C/S结构 服务器 - 客户机,即 Client - Server ( C/S )结构。 C/S 结构通常采取两层结构。服务器负责数据的 管理,客户机负责完成与用户的交互任务。客户机是因特网上访问别人信息的机器,服务器则是提 供信息供人…...
IIC及OLED实验
I2C (Inter-Integrated Circuit): I2C 是一种用于在芯片之间进行短距离数字通信的串行通信协议。它允许多个设备通过两根导线(一根数据线 SDA 和一根时钟线 SCL)进行通信。I2C 常常用于嵌入式系统中连接传感器、存储器、显示屏和其他外设。 数据线和时钟…...
day6 力扣公共前缀--go实现---对字符串的一些思考
今日份知识: curl -x 指定方法名 请求的url -d 请求体body里面的内容 //curl命令 curl -x Get 127.0.0.1:8080/add/user -d jinlicurl如果不指定方法,默认使用get方法,在go里面,get方法到底可以不可以把内容数据写在body里面传…...
27.Java程序设计-基于Springboot的在线考试系统小程序设计与实现
1. 引言 随着数字化教育的发展,在线考试系统成为教育领域的一项重要工具。本论文旨在介绍一个基于Spring Boot框架的在线考试系统小程序的设计与实现。在线考试系统的开发旨在提高考试的效率,简化管理流程,并提供更好的用户体验。 2. 系统设…...
Redis可视化工具Redis Desktop Manager mac功能特色
Redis Desktop Manager mac是一款非常实用的Redis可视化工具。RDM支持SSL / TLS加密,SSH隧道,基于SSH隧道的TLS,为您提供了一个易于使用的GUI,可以访问您的Redis数据库并执行一些基本操作:将键视为树,CRUD键…...
【C++】揭开运算符重载的神秘面纱
目录 一、引言 优点 二、介绍 1.定义 2.语法 三、示例 1.加法运算符重载 2.一元运算符重载 3.友元函数 4.流插入和流提取 5.自增自减运算符 总结 一、引言 何为运算符重载?运算符重载,是C中的一项强大特性,赋予了程序员在自定义类…...
竞赛保研 基于LSTM的天气预测 - 时间序列预测
0 前言 🔥 优质竞赛项目系列,今天要分享的是 机器学习大数据分析项目 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/po…...
前端常用的开发工具
前端常用的开发工具🔖 文章目录 前端常用的开发工具🔖1. Snipaste--截图工具2. ScreenToGif--gif图片录制3. Typora--Markdown编辑器4. notepad--文本代码编辑器5. uTools--多功能工具6. EV录屏--录屏软件7. Xmind--思维导图8. Apifox -- 接口调试9. Tor…...
鸿蒙开发语言介绍--ArkTS
1.编程语言介绍 ArkTS是HarmonyOS主力应用开发语言。它在TypeScript (简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。 2.TypeScript简介 自行补充TypeScript知识吧。h…...
关于“Python”的核心知识点整理大全36
目录 13.4.4 向下移动外星人群并改变移动方向 game_functions.py alien_invasion.py 13.5 射杀外星人 13.5.1 检测子弹与外星人的碰撞 game_functions.py alien_invasion.py 13.5.2 为测试创建大子弹 13.5.3 生成新的外星人群 game_functions.py alien_invasion.py …...
安装nodejs,配置环境变量并将npm设置淘宝镜像源
安装nodejs并将npm设置淘宝镜像源 1. 下载nodejs 个人不喜欢安装包,所以是下载zip包的方式。这里我下载的node 14解压包版本 下载地址如下:https://nodejs.org/dist/v14.15.1/node-v14.15.1-win-x64.zip 想要其他版本的小伙伴去https://nodejs.org/di…...
12.18构建哈夫曼树(优先队列),图的存储方式,一些细节(auto,pair用法,结构体指针)
为结构体自身时,用.调用成员变量;为结构体指针时,用->调用成员变量 所以存在结构体数组时,调用数组元素里的成员变量,就是要用. 结构体自身只有在new时才会创建出来,而其指针可以随意创建 在用new时&…...
《Python》面试常问:深拷贝、浅拷贝、赋值之间的关系(附可变与不可变)【用图文讲清楚!】
背景 想必大家面试或者平时学习经常遇到问python的深拷贝、浅拷贝和赋值之间的区别了吧?看网上的文章很多写的比较抽象,小白接收的难度有点大,于是乎也想自己整个文章出来供参考 可变与不可变 讲深拷贝和浅拷贝之前想讲讲什么是可变数据类型…...
使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错问题
目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序,查看库与库的依赖关系,查看出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总(专栏文章列表&…...
Python编程题目答疑「Python一对一辅导考试真题解析」
你好,我是悦创。 待会更新~ 更新计划 答案 题目 记得点赞收藏! 题目 之后更新 Solution Question 1 # 读取输入 a float(input("请输入实数 a: ")) b float(input("请输入实数 b: ")) c float(input("请输…...
Python---搭建Python自带静态Web服务器
1. 静态Web服务器是什么? 可以为发出请求的浏览器提供静态文档的程序。 平时我们浏览百度新闻数据的时候,每天的新闻数据都会发生变化,那访问的这个页面就是动态的,而我们开发的是静态的,页面的数据不会发生变化。 …...
在服务器上部署SpringBoot项目jar包
以下是在服务器上部署Spring Boot项目jar包的步骤: 打包项目: 使用IDEA或者命令行工具(如Maven或Gradle)将Spring Boot项目打包为一个可执行的jar文件。如果使用Maven,可以在项目的根目录下运行以下命令来打包项目&…...
[python]python实现对jenkins 的任务触发
目录 关键词平台说明背景一、安装 python-jenkins 库二、code三、运行 Python 脚本四、注意事项 关键词 python、excel、DBC、jenkins 平台说明 项目Valuepython版本3.6 背景 用python实现对jenkins 的任务触发。 一、安装 python-jenkins 库 pip install python-jenkin…...
Python生成圣诞节贺卡-代码案例剖析【第18篇—python圣诞节系列】
文章目录 ❄️Python制作圣诞节贺卡🐬展示效果🌸代码🌴代码剖析 ❄️Python制作圣诞树贺卡🐬展示效果🌸代码🌴代码剖析🌸总结 🎅圣诞节快乐! ❄️Python制作圣诞节贺卡 …...
第十一篇:《性能压测基础:JMeter线程模型与压测策略设计》
完成了接口功能测试后,我们将正式进入性能压测领域。性能压测的核心是模拟真实用户并发访问,评估系统在不同负载下的响应能力。本文将从 JMeter 的线程模型出发,讲解如何设计合理的压测策略(基准测试、负载测试、稳定性测试&#…...
3步搞定Windows风扇噪音:用免费软件实现智能散热控制
3步搞定Windows风扇噪音:用免费软件实现智能散热控制 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/…...
BallonTranslator:3分钟搞定漫画翻译的终极AI工具,完全免费开源!
BallonTranslator:3分钟搞定漫画翻译的终极AI工具,完全免费开源! 【免费下载链接】BallonsTranslator 深度学习辅助漫画翻译工具, 支持一键机翻和简单的图像/文本编辑 | Yet another computer-aided comic/manga translation tool powered by…...
Claude API代理服务部署与定制:从零构建企业级AI网关
1. 项目概述与核心价值最近在折腾AI应用开发,特别是想把Claude的API能力整合到自己的项目里,发现直接调用官方API虽然稳定,但在一些特定场景下,比如需要统一接口管理、增加自定义逻辑层,或者想对请求/响应做些“手脚”…...
供水泵恒压变频控制系统:备用泵自动投切,保障供水不间断
供水泵恒压变频控制系统是一套融合变频调速、PID闭环控制与智能多泵管理的自动化节能供水解决方案,核心是按需供水、稳压节能、无人值守。 一、核心原理压力采集:管网压力传感器实时采集水压(0~1.6MPa)。偏差计算:PLC/专用控制器将实测值与设…...
别再只会轮询了!STM32CubeMX配置USART中断,从原理到调试一条龙指南
STM32串口中断实战:从轮询到事件驱动的效率跃迁 在嵌入式开发中,串口通信就像系统的神经末梢,负责与外界交换关键信息。传统轮询方式如同不断拨打电话确认消息,而中断机制则像设置来电提醒——只有当数据真正到达时才会唤醒CPU。这…...
技能设计指南:用产品思维构建个人可衡量技能体系
1. 项目概述与核心价值最近在和一些做产品、运营的朋友聊天,发现一个挺有意思的现象:大家手上都有一堆“技能”,比如会写文案、会做数据分析、会用某个设计软件,但真到了要系统性地提升自己,或者向别人清晰展示自己能力…...
Simulink实战----从零搭建Boost变换器仿真模型
1. 为什么选择Simulink搭建Boost变换器模型 Boost变换器作为电力电子领域的经典拓扑结构,在手机充电器、LED驱动电源等场景中随处可见。但实际搭建硬件电路调试时,经常会遇到MOS管烧毁、电感啸叫等问题。三年前我刚入行时就曾连着烧坏三个MOS管ÿ…...
STL文件可视化革命:stl-thumb技术解析与实践指南
STL文件可视化革命:stl-thumb技术解析与实践指南 【免费下载链接】stl-thumb Thumbnail generator for STL files 项目地址: https://gitcode.com/gh_mirrors/st/stl-thumb 在3D打印和计算机辅助设计的日常工作中,设计师和工程师们面临着一个共同…...
Windows系统管理终极神器:Chris Titus Tech WinUtil完整指南
Windows系统管理终极神器:Chris Titus Tech WinUtil完整指南 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil 你是否厌倦了每次重装…...
