Vue 3将变得更快

Screenshothot-1
今年在前端世界上最引人注目的事件之一是Vue next知识库的发布-这是VueJS第三版功能的一部分。 本文概述了VueJS的新杀手级功能。 在本文发表时,该存储库处于Pre-Alpha状态。 可以在路线图中查看发布计划

背景知识


2018年2月,Vue.js的创建者Evan You 分享了他对流行框架版本3的计划

  • 将功能分解为软件包以隔离范围
  • TypeScript出现在代码库中
  • Vue 3将与第二个版本向后兼容(即不会破坏旧代码)
  • 3.0版中的观察者基于Proxy,它将提高渲染速度并消除Object.defineProperty施加的许多限制。
  • 您将能够使用新的renderTrackedrenderTriggered挂钩首次亮相renderTriggered
  • 由于引入了树抖动(不包括构建中未使用的指令),因此压缩后的框架大小将小于10kb
  • 插槽优化
  • vue 3中的性能将提高100%

内置组件和指令运行时帮助器(v模型)等功能现在可以按需导入并且可摇树
埃文你
编译器将跟踪指令的存在并将其包括在编译阶段的构建中。

在使用Vue 3的过程中,Evan拒绝将组件重写为类,而是实现了功能性API。

由于新版本将使用IE中不支持的代理,因此Evan计划为IE11创建一个单独的内部版本。 总共分四个阶段进行:

  1. Alpha阶段-编译器和ssr渲染完成的阶段
  2. Beta阶段-主库完成阶段(Vue Router,Vuex,Vue CLI,Vue DevTools)
  3. RC阶段-包括Vue 2.0的预发行阶段
  4. IE11版本
  5. 最终发行

埃文(Evan)计划在2019年发布最终版本,但该项目仍处于测试前阶段。

Vue 3将更快


由于有了许多创新,Vue 3的速度将比以前的版本快2倍。

基于代理的观察和反应


一项重大创新是将监视对象的机制从Object.defineProperty的获取方法和设置方法更改为Proxy。 现在,Vue可以在不使用Vue.set和Vue.delete的情况下跟踪反应对象的属性的删除和添加。 这项创新将渲染和脚本编写的速度提高了,并将内存消耗减少了2倍! 您可以通过下载Ilya Klimov存储库来比较Vue 2和Vue 3的性能

Vue 2(左)和Vue 3(前Alpha阶段,右)的性能比较
Screenshothot-1

多亏了代理,当更改Vue 2中未跟踪的对象操作时,反应性不会丢失。 现在,Vue不会递归地遍历对象的属性来计算更改。

什么是诺言:

  • 后代和父母独立重画
  • Vue 3大小从压缩形式的20kb减少到10kb
  • 添加了TypeScript

其他优化:

  • Vue 3将记住静态内容并仅修补动态数据
  • 静态道具上架范围
  • 为了便于开发,Vue 3代码被分解为模块化程序包。
  • 运行时核心程序包跨平台制作
  • Evan代替了类,而添加了设置函数和挂钩,使代码清晰,有条理和可重用*
  • 时间分片*。 JS代码执行被分割为多个部分,而不会阻止用户与应用程序的交互

星号表示实验性API
更新: 后来,埃文(Evan)决定放弃时间限制。

受HOC的启发,Reacta Evan通过可重用的逻辑和自定义钩子实现了设置功能。 与mixins不同,生命周期挂钩不会相互覆盖。

增强型VDom补丁


静态内容操纵杆

Screenshothot-2

编译模板时,静态内容将移出VDom修补程序。 Vue受Svelte的启发来做到这一点:

 <div>Hello, {{name}}</div> 

在这里,将传递更改后的对象和上下文。 如果更改包含响应变量,则将在上下文中对其进行更新。

 p(changed, ctx) { if(changed.name) { set_data(t1, ctx.name); } } 

在之前的实现中,Vue编译器遍历了所有节点,包括静态节点:

 function render(){ const children = []; for(let i = 0; i < 5; i++) { children.push(h('p', { class: 'text' }, i === 2 ? this.message : 'Lorem upsum')) } return h('div', { id: 'content' }, children) } 

新模板编译策略


在新版本中,模板分为多个块:

选择002

  • 模板分为多个块
  • 每个块内的节点结构是完全静态的。
  • 要跟踪一个块中的动态值,只需要放置一个平面数组即可

使用新策略,性能直接取决于动态内容的数量,而不是模板的大小。

Vue 3将更好地适应大型项目


大型项目在使用Vue时面临以下问题:

  1. 不完善的TypeScript支持
  2. 大量难以支持的组件
  3. 缺乏简单的模式来重用代码

最初,计划添加类来支持TS。 但是Vue团队遇到了问题:


Evan的团队请求TC39专家的帮助,发现类似的实现可能会与将各种prop和属性混合到Vue上下文中的插件发生冲突。

这些问题有可能由装饰器解决,但它们仍在开发中。

合成API


Vue团队受到React钩子的启发,并决定创建一个类似的API。 它是可选的,正在开发和讨论中,因此某些名称可能会更改。
更改的主要概念是更合理地组织组件代码,将其分为语义块。 您可以在文档中阅读有关composition API的更多信息。

使用Vue 3的示例。组件分为逻辑功能,在其中可以使用反应性和生命周期挂钩。

从composition API导入新的钩子:

 import { reactive, computed, onMounted } from '@vue/composition-api'; export default { setup() { const { state } = countAnimal("rabbit") const { getType, anotherState } = anotherCount() return { state, getType, anotherState } } } 

countAnimal函数具有反应性计数,动物增量方法。 使用奇数计数器,动物的名称会更改。 计数器在安装组件时启动。

 function countAnimal(name) { const state = reactive({ count: 0, animal: computed(() => state.count % 2 ? name : 'bear') }) function increment() { setTimeout(() => { state.count++; increment() }, 1000) } onMounted(() => { increment() }) return { state } } 

我们创建另一个函数anotherCount ,其中还包含带有计数器和动物名称的增量状态方法。 getType方法从模板传递动物的名称。

 function anotherCount() { const anotherState = reactive({ count: 0, animal: 'fox' }) function getType(name) { return name == 'bear' ? 'slow' : 'fast' } function increment() { setTimeout(() => { anotherState.count+=10; increment() }, 1000) } onMounted(() => { increment() }) return { getType, anotherState } } 

该模板显示2个计数器和2个动物名称。 奔跑的类型根据动物的名称而有所不同。

 <template> <div> <div>Count {{state.animal}}: {{ state.count }}</div> <div>{{state.animal}} runs {{getType(state.animal)}}</div> <div>Another: Count {{anotherState.animal}}: {{ anotherState.count }}</div> </div> </template> 

安装程序中使用了新的挂钩, 而不会破坏旧的API。 请注意, onMounted是指单个组件生命周期挂钩。

此api有几个优点:

  • 生命周期挂钩不会互相摩擦
  • 明确的属性来源
  • 没有创建其他组件实例

结论


上面列出了Vue 3中最重要的更改,其中大部分改进都隐藏在编译器生成的代码的幕后。

主要改进:

  • 生成的代码最适合JS编译器
  • 生成捆绑更容易
  • 父/子组件重绘归功于改进的修补算法

Vue已将自己确立为最快,最理想的框架之一。 新版本将变得更快,更轻松。 Vue 3非常适合当今的移动和面向性能的Web。 有关未来更改的评论可以留在官方RFC中 (要求提供评论)。
PS:感谢您纠正错别字。

Source: https://habr.com/ru/post/zh-CN477228/


All Articles