一文看懂Vue 3.0的优化

Vue.js框架演进的过程

Vue.js 1.x —》Vue.js 2.x
  • 引入了虚拟Dom
  • 为后续为服务端渲染,以及跨端框架weex提供了基础
Vue.js 2.x 作者发现的痛点
  • 源码自身的维护性 =》源码
  • 数据量大后带来的渲染和更新的性能问题 =》性能
  • 兼容性,一些项舍弃但为了兼容一直保留的鸡肋API =》语法
作者希望给开发人员带来的
  • 更好的编程体验
  • 更好的TypeScript支持
  • 更好的逻辑复用实践
  • 更好的性能和更小的体积

Vue.js 3.0 主要做了哪些优化

一、源码优化

源码的优化主要体现在: 使用monorepo管理源码TypeScript开发源码

目的是为了让代码更易于开发和维护

更好的代码管理方式:monorepo
  • 相对于Vue2.0的源码组织方式,monorepo把这些模块拆分为不同的package,每个package都有各自的 API类型定义测试
  • 这样使模块拆分的更细,职责划分更明确,模块之间的依赖关系也更加明确
  • 开发人员也更易阅读、理解和修改模块源码,提高代码的可维护性
  • package(比如reactivity响应式库)是可以独立于Vue.js使用的
  • 这样用户如果只想使用Vue.js 3.0的相应式能力,可单独依赖这个响应式而不用依赖整个Vue.js,减少了引用包的体积大小,而Vue.js 2.x 是做不到这一点的。
有类型的JavaScript:TypeScript

二、性能优化

移除一些冷门的feature
引入tree-shaking的技术

依赖ES2015模块语法的静态结构(即import和export)通过编译阶段的静态分析,找到没有引入的模块并打上标记。然后压缩阶段会被压缩工具进行删除没有用到的代码
tree-shaking

三大打包工具的tree-shaking对于无用代码,无用模块的消除,都是有限的,有条件的。tree-shaking对函数效果较好,类消除实验中,rollup,webpack
全军覆没,都没有达到预期

如果你在项目中没有引入Transition、KeepAlive等组件,你么它们的代码就不会打包,这样也就间接达到了减少项目引入的Vue.js包体积的目的。

三、数据劫持优化

数据是响应式

Dom是数据的一种映射,数据变化后可以自动更新Dom,用户只需要专注于数据的修改,没有其余的心智负担。
如果要实现,必须劫持数据的访问和更新
当数据改变后,为了自动更新DOM,那么就必须劫持数据的更新
也就是说当数据发生改变后能自动执行一些代码去更新DOM

Vue.js怎么知道更新哪一片DOM呢?

因为在渲染DOM的时候访问了数据,我们可以对它进行访问劫持 这样就在内部建立了依赖关系,也就知道数据对应的DOM是什么了
在这里插入图片描述

Vue2.x使用的是Object.defineProperty来实现响应式的缺陷
  • 必选先知道需要拦截的Key是什么,所以并不能检测对象属性的添加和删除,尽管官方给出来$.set 和 $.delete的实例方法,但是还是增加了心智负担。
  • 检讨层级比较深的对象,官方会进行层次遍历进行defineProperty,如果对象层级深,就会有较大的性能负担。
  • 不能检测数组的变化,通过重写数组api来实现响应式
Vue3.x 使用了Proxy API 做数据劫持
  • 因为检测的目标是对象,所以有效的解决了Object.defineProperty来实现响应式的缺陷
  • 注意的是,Proxy API 并不能监听到内部深层次的对象变化,因此Vue.js3.x的处理方式是在getter中区递归响应式这样的好处是 真正访问到内部对象才会变成响应式,而不是无脑递归,这样无疑也在很大程度上提升了性能。

四、编译优化

vue.js2.x的渲染流程

在这里插入图片描述

  • 上面说的响应式就是发生在init阶段
  • 同时template 的compile render vnode阶段是可以在编译阶段离线完成,并非一定要在运行时完成。
  • 所以想要优化整个vue运行时,处了数据劫持部分的优化,我们可以在耗时相对较多的patch阶段想办法
vue3.x通过在编译阶段优化编译的结果,实现运行时patch过程的优化

vue.js2.x的数据更新并触发重新渲染的粒度是组件级的:
在这里插入图片描述
虽然vuejs2.0能保证触发更新的组件最小化,但是在单个组件内部依然需要遍历该组件的vnode树,这样会导致vnode的性能和模板大小正相关,更动态节点的数量无关,当一些组件,模板只有少量动态节点时,这些遍历都是性能的浪费。
理想状态只需要diff 组件内动态修改的节点即可

vue3.x 通过编辑阶段对静态模版的分析,编译生成了Block tree

Brock tree
  • Block tree 是一个将模板 基于动态节点 指令切割的嵌套区块,每个区块的内部结构苏 固定的,每个区块只需要以一个Array来追踪自身包含的动态节点
  • 借助Block tree,Vue.js 将vnode更新性能由与模板整体大小相关提升为 与动态内容的数量相关 (这是一个特别大的性能突破)
Vue3.0在编译阶段 还包含了对Slot的编译优化事件监听函数的缓存优化,并且在运行时重写了diff算法

五、语法API优化:Composition API

优化逻辑组织

Vue1.x 和Vue2.x 编写组件本质就是在编写一个 “包含了描述组件选项的对象”,我们把他成为Options API(好处在于十分符合直觉思维,对于新手来说容易上手和理解)

Options API

  • Options API 的设计是按照methods、computed、data、props这些不同的选项分类
  • 当组件小的时候,这种分类方式一目了然;
  • 但是在大型组件中,一个组件可以有多个逻辑关注点,当使用Options API的时候,每一个关注点都有自己的Options,如果需要修改一个逻辑点关注点,就需要在单个文件中不断上下切换和寻找

新的API:Composition API
就是将摸个逻辑关注点相关的代码 全部放在一个函数里
这样当需要修改一个功能时,就不在需要再文件中跳来跳去

优化逻辑复用

Vue.js 2.x =》mixins去复用逻辑,当一个组件混入大量mixins时

  • 没有mixins都是可以定义自己的props、data,它们直接是无感的,所以很容易定义相同的变量,导致命令冲突
  • 对于组件而言,如果模板中使用不在当前组件中定义的变量,那么就会不太容易知道这些变量在哪里定义的,这就是数据来源不清晰

Vue3.x Composition API类似hooks的使用方式,所以天然的有逻辑复用方面的优势,同时除了在 逻辑复用 方面有优势,也会有更好的类型支持

  • 因为它们都是一些函数,在调用函数时,自然所以的类型就是被推到出来了,不像Options API 所以的东西使用 this
  • 另外,Composition API 对 tree-shaking友好,代码也更容易压缩
  • Vue3.x Composition API属于API的增强,并不属于Vue3.0的范式,当组件很简单时,也可以使用Options API。

五、引入RFC:是每个版本改动可控

  • 大规模启用RFC( Request For Comments)
  • 了解每一个feature采用或被废掉的前因后果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥肥呀呀呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值