Vapor Mode:Vue.js 的速度与激情,代码界的闪电侠

大家好,我是宝哥。

在快速发展的网络开发世界中,创新的Vue.js团队给我们带来了Vapor Mode。这个新模式优化了Vue的核心渲染过程,帮助我们的应用程序像轻烟一样运行,开发者无需深入复杂的优化工作。

在这篇文章中,我们将揭示Vapor Mode如何优雅地提升应用效率,以及如何开始尝试使用它。但首先,让我们先弄清楚为什么要开发Vapor Mode。

为什么需要Vapor Mode?

如果你之前使用过JavaScript框架,你很可能熟悉虚拟DOM的概念。它涉及创建和更新DOM的虚拟表示,并将其存储在内存中以与实际DOM同步。由于更新VDOM比更新实际DOM要快,它为框架提供了相对低成本地对VDOM进行必要更改的自由。

在Vue中,其基于VDOM的渲染系统将我们模板部分的代码转换为实际的DOM节点。该系统还有效管理节点的变更,这些变更可以通过JavaScript函数、API调用等动态生成。

1d3b8215a4b327b9c36d4283092d7eb2.png

虽然VDOM提高了速度和性能,但在更新DOM时,仍然需要遍历节点树并比较每个虚拟节点的属性以确保准确性。这个过程还包括为树的每个部分生成新的VNodes,无论是否有变更,这可能导致不必要的内存压力。

但是,在Vue中,引入了另一种方法来解决这个问题,称为“编译器感知的虚拟DOM”。

这是一种混合方法,引入了一些优化概念来帮助解决这个问题,包括:

  1. 静态提升(Static Hoisting)

  2. 补丁标志(Patch Flags)

让我们更仔细地看看这些,以更清楚地了解Vue的渲染系统,这样我们就能更好地理解Vapor Mode带来了什么。

Vue中的静态提升

静态提升是一种技术,它自动从渲染函数中提取VNode创建,允许在多次重新渲染中重用VNodes。这种优化是有效的,因为这些VNodes随时间保持不变。

例如,给定这段代码:

<div>
  <p class="vue">Vue.js是酷的</p>
  <p class="solid">Solid.js也是酷的</p>
  <p>同意吗?{{agree}}</p>
</div>

当使用静态提升技术编译时,我们得到:

import { createElementVNode as _createElementVNode, ... } from "vue"
const _hoisted_1 = /*#__PURE__*/_createElementVNode("p", { class: "vue" }, "Vue.js是酷的", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createElementVNode("p", { class: "solid" }, "Solid.js也是酷的", -1 /* HOISTED */)
// ... 其他代码

在上面的例子中,你会看到有两个变量:_hoisted_1_hoisted_2。它们包含将保持不变的静态代码,这些代码被提升或从渲染函数中拉出来,以避免重新处理不是动态的代码。

我们声明并重新渲染最后一个 p 标签中的元素,因为该元素包含一个动态变量,这个变量随时可能改变。

值得注意的是,当有足够的连续静态元素时,它们将被合并为一个单一的静态Vnode(使用 createStaticVNode),并传递给渲染函数。

让我们看一个例子:

<div>
  <p class="vue">Vue.js是酷的</p>
  <p class="solid">Solid.js也是酷的</p>
  <p class="vue">Vue.js是酷的</p>
  <p class="solid">Solid.js也是酷的</p>
  <p class="solid">React也很酷</p>
  <p>{{agree}}</p>
</div>

当编译时,我们得到:

import { createElementVNode as _createElementVNode, ... } from "vue"
const _hoisted_1 = /*#__PURE__*/_createStaticVNode("<p class=\\"vue\\">Vue.js是酷的</p><p class=\\"solid\\">Solid.js也是酷的</p>..., 5)
// ... 其他代码

现在,我们不仅有多个hoisted常量,而只有一个包含模板所有静态代码的常量。

Vue中的补丁标志

补丁标志允许Vue智能地更新DOM。它们用于标识具有动态绑定的元素所需的更新类型,例如classidvalue等。与全面更新方法不同,它只根据这些标志选择性地更新已更改的内容,而无需重新渲染整个组件或检查每个元素。

这不仅通过只关注已更改的元素来加快更新过程,而且还避免了不必要的操作,比如调整未更改的元素的顺序。

这是通过在更新时将VNode传递给渲染函数来完成的。createElementVNode函数接受一个数字作为其最后一个参数。这个数字表示一个补丁标志,它指示在调用渲染函数时需要更新的动态绑定的类型。

让我们看看这个在行动中的例子:

<div :class="{ active }"></div>
<input :id="id" :value="value" :placeholder="placeholder">
<div>{{ dynamic }}</div>

这里,我们有一个带有动态类activediv,一个带有动态idvalueplaceholderinput元素,还有一个带有dynamic文本的div

当这段代码被编译时,我们得到这个:

import { normalizeClass as _normalizeClass, ... } from "vue"
export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createElementBlock(_Fragment, null, [
    _createElementVNode("div", {
      class: _normalizeClass({ active: _ctx.active })
    }, null, 2 /* CLASS */),
    // ... 其他代码
  ], 64 /* STABLE_FRAGMENT */))
}

在这里,每个createElementVNode函数接受一个数字,该数字表示作为其最后一个参数的属性。第一个数字是2,表示一个类,8表示属性,64表示一个稳定的片段。你可以在GitHub上找到每个标志的完整列表。

通过这种方法,Vue可以相对于React和Svelte表现得更好,如下所示图表。

bba77b482699b897630f568c1e9ef6a0.png

Vapor Mode的理由

尽管Vue的方法已经比较精细,但仍存在一些性能问题。这些问题包括不必要的内存使用、树差异比较以及VDOM的缺陷。

Vapor Mode的创建就是为了解决这些问题。

Vapor模式是一种替代的编译策略,旨在通过将代码编译成更高效的JavaScript输出,使用更少的内存,减少运行时支持代码,并避免上面说明的编译器感知的VDOM方法的缺陷,从而提高你的Vue.js应用程序的性能。

Vapor Mode的一些好处包括:

  • 它是可选的,不影响现有的代码库。这意味着你可以立即开始使用Vapor Mode来优化你的Vue 3应用程序的性能,而无需对代码进行任何更改。

  • 如果应用程序中只使用Vapor组件,你可以完全从捆绑包中删除VDOM运行时,减少基础运行时大小。

❕ Vapor模式将只支持组合API和<script setup>

Vue的Vapor Mode如何工作

根据Vue(和Vite.js)的创建者Evan You的说法,Vapor模式受到Solid.js的启发,Solid.js是一种用于创建用户界面的声明性JavaScript库,它采用了一种不同的编译和渲染节点的方法。

与使用虚拟DOM不同,它将模板编译为真实的DOM节点,并使用细粒度的反应进行更新。像Solid一样,Vue在其反应性系统中使用代理和基于读取的自动跟踪。

给出我们上一个例子中的相同代码,开启Vapor Mode时,它编译并给我们:

import { renderEffect as _renderEffect, ... } from 'vue/vapor'
const t0 = _template("<div></div>")
const t1 = _template("<input>")
export function render(_ctx) {
  const n0 = t0()
  const n1 = t1()
  const n2 = t0()
  _renderEffect(() => _setClass(n0, { active }))
  _renderEffect(() => _setDynamicProp(n1, "id", id))
  // ... 其他代码
  return [n0, n1, n2]
}

在编译后的代码中,你会看到来自vue/vapor包的renderEffectsetClasssetDynamicPropsetTexttemplate的导入。

让我们看看每个函数的作用。

  1. renderEffect:此函数负责监听类、属性和文本的更改,以确保在更新时对这些节点进行正确的更改。

  2. setClass:顾名思义,此函数将类分配给节点元素。它接受两个参数:一个element(或node)和它分配给元素的class

  3. setDynamicProp:此函数用于设置元素上的动态属性。它需要三个参数:elementkeyvalue。这些用于确定每次调用此函数时分配或更新的适当值。

  4. setText:此函数接受一个node和可能的值。它将给定的值设置为节点的textContent,同时还验证内容是否已被修改。

  5. template:此函数接受一个有效的HTML字符串并从中创建一个元素。检查该函数时,我们可以看到它使用基本的DOM操作方法。具体来说,使用document.createElement创建元素。然后使用innerHTML追加元素的内容,innerHTML接受HTML字符串。

通过这些函数的组合,Vue可以将你的组件和应用程序编译成更快、更高效的代码,最终提高应用程序的性能和捆绑包大小。

为了帮助开发者熟悉Vapor Mode,Vue团队发布了一个演示 和模板浏览器。

示例允许你比较启用和未启用Vapor模式时代码的编译版本。

d52ca2b26e6f1d757cc2df9ffddd5a2b.png

在示例内,你可以检查代码的CSS、JS和SSR输出。它还允许你切换Vapor模式功能,轻松比较输出的差异。

模板浏览器类似于示例,但它只提供代码的JavaScript输出,并提供一些选项,如SSR、模块等。

9edc7fa03acd001912df9d6821d1f673.png c984ae2378d4f3519a586b47b4f4a577.png

使用Vapor Mode

根据Vapor Mode仓库,这里有一个使用Vapor模式构建组件的示例:

<script setup lang="ts">
import {
  onBeforeMount,
  onMounted,
  onBeforeUnmount,
  onUnmounted,
  ref,
} from 'vue/vapor'

const bar = ref('update')
const id = ref('id')
const p = ref<any>({
  bar,
  id: 'not id',
  test: 100,
})

function update() {
  bar.value = 'updated'
  p.value.foo = 'updated foo'
  p.value.newAttr = 'new attr'
  id.value = 'updated id'
}

function update2() {
  delete p.value.test
}

onBeforeMount(() => console.log('root: before mount'))
onMounted(() => console.log('root: mounted'))
onBeforeUnmount(() => console.log('root: before unmount'))
onUnmounted(() => console.log('root: unmounted'))
</script>

<template>
  <div>
    root comp
    <button @click="update">update</button>
    <button @click="update2">update2</button>
    <input :value="p.test" :placeholder="p.bar" :id="p.id" />
  </div>
</template>

与Vue开发者习惯的方式不同,注意我们是如何在vue/vapor包中导入refonBeforeMountonMounted和其他函数的。

这些函数都是组合API的一部分,唯一的区别是它们现在从vapor包导入,该包不依赖于VDOM。

这允许我们在应用程序中使用Vapor Mode组件和非Vapor Mode组件,而无需额外配置。

支持的功能

作为提高性能和降低基础运行时大小的努力的一部分,Vapor Mode将只支持组合API,并且只能与<script setup>一起使用。

随着Vue团队的持续工作,我们将看到Vapor Mode支持的功能的更多示例,但有一点是明确的:Vapor Mode组件中支持的功能将与非Vapor模式组件的工作方式相同。

总结

现在我们已经看到了Vue当前如何使用编译器感知的虚拟DOM方法编译代码及其缺点,我们将看到Vapor Mode的性能如何,以及它如何实现更小的捆绑包大小和改进的性能的承诺。随着我们继续等待发布日期,熟悉Vapor Mode的可用功能是很重要的,这可以通过Vapor演示完成。


最后,如果你觉得宝哥的分享还算实在,就给我点个赞,关注一波。分享出去,也许你的转发能给别人带来一点启发。

关注我,加星标,明天见!

Vue 3 将推出新特性,可以抛弃虚拟DOM了!

关注下方宝哥微信,进宝哥前端开发11群,

获取我公众号整理的所有资料,

包括前端电子书,面试资料,简历模板和副业资料等!

01ef3e66084b3928f696e6a43c00fcb3.png

以上,如果本文对你有所启发,欢迎点“2efdcfcbd8417b12f32ef43d1906fa32.gif在看、点赞”支持下吧! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/646304.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

贝叶斯算法:机器学习中的“黄金法则”与性能提升之道

&#x1f440;传送门&#x1f440; &#x1f50d;机器学习概述&#x1f340;贝叶斯算法原理&#x1f680;贝叶斯算法的应用✨文本分类✨医疗系统 &#x1f496;贝叶斯算法优化✨贝叶斯算法优化的主要步骤✨贝叶斯算法优化的优点✨贝叶斯算法优化的局限性 &#x1f697;贝叶斯算…

详细分析tcping的基本知识以及用法

目录 前言1. 安装配置2. 基本知识3. Demo 前言 针对ping的基本知识推荐阅读&#xff1a;详细分析ping的基本知识以及常见网络故障的诊断&#xff08;图文解析&#xff09; 1. 安装配置 针对Window的下载如下&#xff1a; 安装路径&#xff1a;tcping官网 下载tcping.exe&a…

【开源】大学生竞赛管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、系统介绍 学生管理模块 教师管理模块 竞赛信息模块 竞赛报名模块 二、系统截图 三、核心代码 一、系统介绍 基于Vue.js和SpringBoot的大学生竞赛管理系统&#xff0c;分为管理后台和用户网页端&#xff0c;可以给管理员、学生和教师角色使用&#xff0c;包括学…

STM32手写超频到128M函数

今天学习了野火的STM32教程学会了如何设置STM32的时钟频率&#xff0c;步骤比较详细&#xff0c;也很容易理解&#xff0c;就是视频教程不能跳着看&#xff0c;只能一节节的看&#xff0c;不然会知识不连贯&#xff0c;造成有些知识不理解&#xff0c;连续着看还是没有什么难度…

闲置商标转让出现这些状态时注意!

近日以前做转让的一个朋友的商标转让证明下来&#xff0c;正好是2个半月&#xff0c;普推知产老杨发现这个时间也太快&#xff0c;以前差不多四个月左右&#xff0c;有些朋友需要购买闲置商标&#xff0c;3个月内所有权就变成自己的。 在购买闲置商标时要注意有一些细节&#x…

创新实训2024.05.26日志:服务端接口实现——用户开启多个会话

1. 概念图 类似于Kimi&#xff0c;文心一言&#xff0c;chatGPT等市面上主流的大模型&#xff0c;我们的大模型也支持同一个用户的多个会话&#xff0c;并且提供支持联系上下文给出解答的能力。 2. 基于会话的对话 在langchain chatchat这个对langchain框架进行二次封装的第三…

GPT-4 与 GPT-4 Turbo有什么区别?

在不断发展的人工智能和自然语言处理领域&#xff0c;OpenAI 的 GPT 系列一直走在最前沿&#xff0c;彻底改变了机器理解和生成类人文本的方式。每一次迭代&#xff0c;进步都会突破可能性的界限。 最新的条目 GPT-4 和 GPT-4 Turbo 引起了人工智能社区内外的极大兴趣和争论。…

推荐13款常用的Vscode插件,提高前端日常开发效率

1. Live Server Live Server 插件是一个用于前端开发的扩展&#xff0c;它的主要作用是提供一个本地开发服务器&#xff0c;以便实时预览和调试网页应用程序。其最大特点在于热重载&#xff0c;即开发者可实时预览代码效果。 因为Live Server 允许开发者在浏览器中实时预览您正…

【C++】详解深浅拷贝的概念及其区别

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C ⚙️操作环境:Visual Studio 2022 目录 什么是拷贝 什么是浅拷贝 什么是深拷贝 深浅拷贝的区别及使用场景 结语 什么是拷贝 在C编程中&#xff0c;拷贝是一个非常重要的概念&#xff0c;对于理解和使用类和对象起…

浅谈JMeter体系结构

JMeter体系结构详解 JMeter是一款功能强大的开源性能测试工具&#xff0c;广泛应用于Web应用、数据库、FTP服务器等多种场景下的负载和压力测试。其灵活的体系结构设计使得测试计划的创建、执行与结果分析变得高效而直观。本文将深入解析JMeter的三维空间体系结构&#xff0c;…

C++实现定长内存池

项目介绍 本项目实现的是一个高并发的内存池&#xff0c;它的原型是Google的一个开源项目tcmalloc&#xff0c;tcmalloc全称Thread-Caching Malloc&#xff0c;即线程缓存的malloc&#xff0c;实现了高效的多线程内存管理&#xff0c;用于替换系统的内存分配相关函数malloc和fr…

基于UDP的TFTP文件传输-实现网盘上传下载功能

数据传输模式&#xff1a;octet(二进制模式) #include<head.h> char* down_up_request(char* buf,char* filename,int rw,int sockfd,struct sockaddr_in in); int download(struct sockaddr_in in,char* filename,char* buf,int sockfd); int upload(struct sockaddr_in…

数据结构(七)查找

2024年5月26日一稿(王道P291) 7.1 查找的基本概念 7.2 顺序查找和折半查找 7.2.1 顺序查找 7.2.2 折半查找 7.2.3 分块查找 7.3 树形查找 7.3.1 二叉排序树(BST)

FFmpeg+QT播放器实战1---UI页面的设计

1、播放器整体布局的设计 该部分使用QT的UI工具&#xff0c;进行整体页面设置&#xff0c;如下图1所示&#xff1a; 2、控制布局的设计 创建ctrBar的UI页面并进行页面布局设置&#xff0c;如下图2所示&#xff1a; 将图1中ctrBarWind对象提升为ctrBar类(该界面替代原先的控…

Modbus TCP转Profinet网关测试配置案例

本案例采用XD-ETHPN20网关做为Modbus TCP通信协议设备与Profinet通信协议设备连接的桥梁。Modbus TCP是一种基于TCP/IP协议的工业通信协议&#xff0c;而Profinet则是用于太网通信的协议。Modbus TCP转Profinet网关可实现这两种不同协议之间的数据交换和传输&#xff0c;极大地…

实在智能TARS:面向垂直领域自主训练的类GPT大模型

一、写在前面 在数字化浪潮的推动下&#xff0c;企业正寻求突破传统生产力的局限&#xff0c;以实现更高效、更智能的运营模式。实在智能科技有限公司的TARS产品&#xff0c;以其前沿的人工智能技术&#xff0c;为企业注入了新质生产力&#xff0c;引领着智能化转型的新潮流。…

数据结构(三)循环链表

文章目录 一、循环链表&#xff08;一&#xff09;概念&#xff08;二&#xff09;示意图&#xff08;三&#xff09;操作1. 创建循环链表&#xff08;1&#xff09;函数声明&#xff08;2&#xff09;注意点&#xff08;3&#xff09;代码实现 2. 插入&#xff08;头插&#x…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(十二)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 我们&#xff0c;继续讲一…

【Django项目】 音乐网站spotify复刻

代码&#xff1a;https://github.com/tomitokko/spotify-clone 注&#xff1a;该项目不是自己提供mp3文件&#xff0c;而是使用spotify 的api接口获取。

用实践结果告诉你为啥说 CloudFlare 是赛博菩萨?

最近几天明月都没有更新博客了,主要是接了几个 CloudFlare 代维配置的活儿,有需要加速优化的,有需要排除疑难故障的,有需要提高防御攻击能力的甚至还有纯粹为了体验“打不死”装逼需要的。总之,各种各样的需求,五花八门的,好在 CloudFlare 都能一一满足,最主要的是这些…