作者|Filip Rakowski
译者|王强
编辑|王文婧
最近关于即将发布的 Vue.js 的第 3 个大版本的消息越来越密集。虽然本文所讨论的内容还没有完全确定下来,但作者已经可以肯定它将是对当前(已经非常出色的)版本的大幅升级。
Vue 团队非常擅长改进框架 API。Evan You 总结了 Vue 3 的几大改进目标:
  • 速度更快。
  • 体积更小。
  • 更易维护。
  • 以原生为目标更容易。
  • 让生活更轻松。

看过 RFC 和相关讨论后,我确信上述所有目标都肯定能实现。本文会带领读者浏览一些个人认为最有趣的更改内容,介绍它们的影响和潜力。

性能优化

我非常重视性能,所以在探索具体的 API 之前我想谈一谈 Vue 3 的性能。可讲的东西是很多的!几乎每个角落都能找到明显的改进!

首先来看 Vue 3 的包大小。

目前,最小化和压缩过的 Vue 运行时大小约为 20kB(当前的 2.6.10 版本为 22.8kB)。Vue 3 的包估计只需一半的体积,因此只有〜10kB!

全局 API tree-shaking

Vue 3 带来了许多诸如更好的模块化之类的优化,而最值得一提的是 Vue 3 源代码将支持 tree-shaking。这意味着如果你不使用它的某些功能(例如keep-alive组件或 v-show 指令),则这些功能将不会包含在你的产品包中。在当前版本中,无论我们使用 Vue 核心中的哪些功能,所有未使用的功能最终都会进入我们的生产代码,因为 Vue 实例是作为单个对象导出的,并且打包器无法检测出代码中使用了对象的哪些属性。

 // Vue 2.x - whole `Vue` object is bundled for production
import Vue from 'vue' Vue.nextTick(() => {})
const obj = Vue.observable({})

为了使全局 API 支持 tree-shaking,Vue 团队决定通过命名导出导入其中的大多数 API,以便打包器可以检测出未使用的代码并删除它们:

 // Vue 3.x - only imported properties are bundled
import { nextTick, observable } from 'vue' nextTick(() => {})
const obj = observable({})
这是一个重大变化,因为以前的全局 API 现在只能通过命名的导出才能使用。这一更改会影响:
  • Vue.nextTick
  • Vue.observable
  • Vue.version
  • Vue.compile(仅限完整构建)
  • Vue.set(仅在 2.x 兼容版本中,很快你就知道为什么了)
  • Vue.delete(与上同)

我们需要一段时间才能完全享受到这一功能的好处,因为它需要在一个在生态系统中的普及过程。Vue 团队将发布兼容版本,因此我们也应该能用那些使用了旧 API 的插件,代价就是影响性能。

支持 tree-shaking 的 JavaScript API 不止一个。在后台,Vue 编译器(将 Vue 模板转换为渲染函数的工具)将检测模板中使用的指令,并对其进行 tree-shaking。以下面的模板为例:

<transition>
<div v-show="ok">hello</div>
</transition>

在被 Vue 编译器处理后,代码差不多会变成下面这个样子:

import { h, Transition, applyDirectives, vShow } from 'vue'

export function render() {
return h(Transition, [
applyDirectives(h('div', 'hello'), this, [vShow, this.ok])
])
}

所有人都会从全局 API tree-shaking 中受益(尤其是我们的用户),但我认为最看重这一功能的是那些制作小型,轻量级网站并只使用 Vue 的一部分功能来开发交互的开发者,他们主要用 Vue 来替代 jQuery 之类的库。

基于代理的响应性

包的大小可能会严重影响你的应用加载时间,但是包被完整下载后,它也应该快速渲染并流畅运行。

Vue 核心团队非常了解这一点,因此我们在运行时性能上也有很大的改进。

首先来看影响最大的部分——一种基于 JavaScript 代理的新的响应系统。当前版本的 Vue 响应系统是基于 Object.defineProperty 的,其存在一些局限。最常见且令人沮丧的一个限制是 Vue 无法跟踪响应对象的属性添加 / 删除。为此我们需要使用 Vue.set 和 Vue.delete 来保证响应系统的运行符合预期。有了 JS 代理后,我们终于可以摆脱这种丑陋的解决方案了。

// Adding a new property to reacitve object in Vue 2.x
Vue.set(this.myObject, key, value)
// Adding a new property to reactive object in Vue 3
this.myObject[key] = value

代理的好处可以从更快的组件初始化和修补中看出来。根据测试,现在的速度是之前的 2 倍!

这种改进尤为重要,因为 Vue 必须使用 getters/setters 来递归地遍历所有对象及其属性,并转换它们。使用代理后,这一过程就变得容易很多。

值得一提的是,使用 JS 代理后,Vue 3 会放弃对 Internet Explorer 的支持(不包括 Edge),但请放心,对于希望支持 IE 的用户来说会有一个兼容版本可用。

时间分片

根据 Evan You 的推文,此功能不会包含在 Vue 3 中。

Vue 3 之后的版本还会带来另一个非常激动人心,但很少被提到的功能,那就是对时间分片的试验性支持。

打个比方来解释什么是时间分片。想象一家甜品店前排了长长的队伍,因为店里在卖镇上最好的冰淇淋。一个人买到冰淇淋后就轮到下一个,以此类推。由于某种原因,大家不知道有哪些口味可供选择。要获取这一信息,你需要直接询问出售冰淇淋的柜台售货员。

在这种情况下,我们最后可能会看到两条队伍——其中一条是想要买冰淇淋的顾客(耐心等待),另一条则是那些希望在决定是否购买冰淇淋之前了解更多口味信息的顾客。后者希望尽快获得这一信息。不幸的是,只有一位女士在卖冰淇淋,她在为“主”队伍中的所有顾客提供完服务之前不会回答任何问题。

对于还没下决定的顾客来说,这并不是最好的体验,他们中的大多数人可能会觉得等那么久并不值当。为了解决这个问题,卖冰淇淋的女士可以在每服务 2 至 3 位顾客后回答一个关于口味的问题。这样一来两条队伍中的顾客都应该会满意这个解决方案。

这正是 CPU 运行 Web 应用程序的工作机制。我们有一条“主”队列(称为“主线程”),需要完成应用的所有主要任务(脚本、渲染等),然后才能响应用户交互。对于某些页面来说,这可能会导致非常糟糕的用户体验,具体取决于 Vue 组件加载或重新渲染所需的时间。

为了让它更加可靠,最好将这一脚本运算过程“切成”小段,并在每小段执行后查看是否有用户输入要处理。这样,无论需要多少次渲染或重新渲染,应用程序都将保持响应状态。这就是在 Vue 3 未来版本中的工作机制。

Evan 用下面的图片展示了 Vue 3 中时间分片功能的例子。请注意脚本执行时间轴中的小间隙,这些间隙是用来处理用户输入的。

轻松识别为什么组件会重新渲染

工具与开箱即用的性能同等重要。据此,我们会在 Vue 3 中看到一个新的生命周期 hook——renderTriggered。我们可以使用它来跟踪和消除不必要的组件重新渲染,将其与时间分片配合使用,就成为了优化运行时性能的非常强大的武器。

const Component = {
// other properties
renderTriggered (event) {
console.log(`Re-render of ` + this.$options.name + ` component`, event)
}
}
还有什么

除了上面提到的这些内容,Vue 3 加入的改进还有很多很多,但本文提到的这些更改可能是影响最大的。大多数未提及的改进将隐藏在 Vue 编译器生成的代码中,或者融入实现细节和算法中。

还有几项改进值得一提:
  • 输出代码将更容易针对 JavaScript 编译器优化。
  • 输出代码通常会更好地优化。
  • 由于改进了补丁算法,将避免不必要的父级 / 子级重新渲染。

总  结

尽管 Vue 已经称得上是目前性能最好的框架之一,但我们还是会在第三版中看到许多重大改进,特别是在包大小和运行时性能等方面。此外 Vue 3 还带来了无数细小的优化。我认为 Vue 3 非常适合现代移动优先和性能导向的 Web 开发工作。

别忘了 Vue 是唯一由社区完全驱动的主流框架。本文列出的所有更改(和其他更多更改)都以 RFC 的形式与社区一起讨论过了。你可以帮助核心团队,表达你对活跃 RFC 的意见,甚至可以提出自己的改进建议。

让我们一起使 Vue 变得更好

【Vuejs】397- Vue 3最值得期待的五项重大更新的更多相关文章

  1. YARN之上的大数据框架REEF:微软出品,是否值得期待?

    YARN之上的大数据框架REEF:微软出品,是否值得期待?   摘要:微软即将开源大数据框架REEF,REEF运行于Hadoop新一代资源管理器YARN的上层.对于机器学习等在数据传输.任务监控和结果 ...

  2. IMCASH:2019年区块链不会风平浪静,至少还有10件事值得期待

    当我们在说2019年是值得期待的一年时,我们还是得做到有根有据.那么,2019年在区块链行业都会发生哪些引导行业风向.影响整个行业的事件呢? 今天,白话区块链带着大家顺着时间线梳理一下. 01 第一季 ...

  3. vuejs学习——vue+vuex+vue-router项目搭建(三)

    前言 vuejs学习——vue+vuex+vue-router项目搭建(一) vuejs学习——vue+vuex+vue-router项目搭建(二) 为什么用vuex:组件之间的作用域独立,而组件之间 ...

  4. vuejs学习——vue+vuex+vue-router项目搭建(二)

    前言 最近比较忙,所有第二章发布晚了,不好意思各位. vuejs学习——vue+vuex+vue-router项目搭建(一) 中我们搭建好了vue项目,我相信大家已经体验了vue其中的奥妙了,接下来我 ...

  5. 下载vuejs,Hello Vue(vscode)

    下载vuejs,Hello Vue(vscode) Hello Vue 下载使用vue.js 动图演示 Vue的基本使用步骤  传送门:https://cn.vuejs.org/v2/guide/in ...

  6. vue中,对象数组多层嵌套时,更新数据更新页面

    vue中的对象和数组的元素直接赋值修改时,是不能响应到view中去的 1.对象更新 this.a={title:'列表1’}; this.a.title='列表2’; <h1>{{a.ti ...

  7. vuejs学习——vue+vuex+vue-router项目搭建(一)

    前言 快年底了却有新公司邀请了我,所以打算把上家公司的学到一下技术做一些总结和分享. 现在vuejs都2.0了,我相信也有很多朋友和我一样实际项目还是选择vue1.0的或者给新手一些参考,不管在选择哪 ...

  8. [Erlang 0115] 2014值得期待的Erlang两本新书

    在2014年的开头就有这样一个令人振奋的好消息,Erlang有一本新书即将出版 <The Erlang Runtime System>,其作者happi在2013年3月份公布了这本书的写作 ...

  9. PHP 7 值得期待的新特性(下)

    这是我们期待已久的 PHP 7 系列文章的第二篇.点此阅读 第一篇本文系 OneAPM 工程师编译整理. 也许你已经知道,重头戏 PHP 7 的发布将在今年到来!现在,让我们来了解一下,新版本有哪些新 ...

随机推荐

  1. Linux下编写-makefile-详细教程(跟我一起写-Makefile-Markdown整理版)

    目录 概述 关于程序的编译和链接 Makefile 介绍 Makefile的规则 一个演示例子 make是怎样工作的 makefile中使用变量 让make自己主动推导 另类风格的makefile 清 ...

  2. 自学python的高效学习方法【python秘籍】

    随着互联网的发展,数据科学概念的普及,Python火得一塌糊涂,为此很多小伙伴想学这门语言,苦于没有正确的学习方法,大部分都放弃了,所以我想总结下经验来帮助大家高效学完python技术!第一.首先学习 ...

  3. nyoj 52-无聊的小明 (模拟, SET)

    52-无聊的小明 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:1 submit:3 题目描述:       这天小明十分无聊,没有事做,但不甘于无 ...

  4. 安装Fedora后

    更新操作系统版本: https://fedoraproject.org/wiki/DNF_system_upgrade    靠谱: 设置ssh:ssh生成公钥私钥.默认root(.ssh/confi ...

  5. 利用Python学习线性代数 -- 1.1 线性方程组

    利用Python学习线性代数 -- 1.1 线性方程组 本节实现的主要功能函数,在源码文件linear_system中,后续章节将作为基本功能调用. 线性方程 线性方程组由一个或多个线性方程组成,如 ...

  6. 十、CSR8670的DFU功能[补充]

    前一篇转载的博文很清楚,全面的介绍了DFU功能的实现步骤.关于DFU功能,你还需要知道以下信息: 一.image.fs,firmware,loader,psr之间的关系 图1-1 image.fs示意 ...

  7. windows anaconda python3.7 import ssl,psycopg2报错

    使用anaconda,本来是为了减少装第三方模块依赖出错问题的. 但是,今天发现,也是有坑啊. 首先 import ssl 报错,import _ssl 说DLL load failed 解决办法:用 ...

  8. 数据库05 使用percona软件来进行数据备份

    1.为什么要与用percona来备份 常见的MySQL备份工具 —跨平台性差 —备份时间长.冗余备份.浪费存储空间 mysqldump备份缺点: —效率较低.备份与还原速度慢,锁表(即备份数据库中的一 ...

  9. python容器类型字典的操作

    字典(dict):由大括号进行描述一组键值对,其键值对之间使用冒号隔开,键值对与键值对之间使用逗号隔开: 注意:字典的key可以为数字,但是不可以重复,因为key是唯一标识符: 1.声明一个字典:语法 ...

  10. Hadoop之HDFS文件系统(二)

    HDFS客户端 通过IO流操作HDFS HDFS文件上传 @Test public void putFileToHDFS() throws Exception{ // 1 创建配置信息对象 Confi ...