Vue3的优化

编译方面

diff方法优化

Vue3对于不参与更新的元素,做静态标记并提示,只会被创建一次,在渲染时直接复用。

vue2中的虚拟dom通过模板创建虚拟节点(js对象),然后使用虚拟节点跟上一次缓存的虚拟节点进行全量的对比。在vue3中做出了改进,在与上次虚拟节点进行对比时候,只对比带有patch flag的节点,并且可以通过flag的信息得知当前节点要对比的具体内容。

hoistStatic 静态提升

把静态的节点进行提升,所有的静态节点都被拿到了渲染函数体外面,也就是说在应用第一次的启动被创建了一次后,之后这些虚拟节点会在每次渲染时候被不停的复用,这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用。

cacheHandlers 事件侦听器缓存

在第一次渲染时会自动生成一个内联的函数,在内联函数里面引用当前的fn,然后把内联函数cache起来,后续的更新会从缓存中读同一个函数,因为是同一个函数,也就没有追踪变化的必要,这样就神奇的把这个span变成了静态的。手写的内联函数也会被cache起来,这样就会避免一些没必要的更新。

<span onClick={() => console.log()}></span>
1

变化侦测

在vue2中实现数据双向绑定,是通过Object.definePropertyd劫持各个属性的getter、setter,在读取数据时触发getter,修改数据时候触发setter。

在vue3中改为用Proxy,但是Proxy只能代理一层,对于深层的无法代理。vue3中利用每次set被拦截之前都会拦截到get操作,所以vue3在get中直接对数据进行reactive,这样就大大减少了递归reactive带来的性能消耗。

全局API分块(Tree Shake机制)

Vue 3源代码将加入tree-shake。这意味着,如果您不使用其某些功能(例如component或者v-show指令),它们将不会包含在您的基础包中。

关于 Tree Shaking

Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination

原理:

  1. ES6 Module引入进行静态分析,故而编译的时候正确判断到底加载了那些模块
  2. 静态分析程序流,判断那些模块和变量未被使用或者引用,进而删除对应代码

更好的 TypeScript 支持

Vue 3是用TypeScript编写的库,可以享受到自动的类型定义提示

Composition API

它以 setup 启动函数作为逻辑组织的入口,暴露了响应式 API 为用户所用,也提供了生命周期函数以及依赖注入的接口,就是将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去。

Composition API响应式的实现依靠一个保存有依赖与更新对应关系的WeakMap数据结构。这里的WeakMap数据结构指的就是ES6提供的WeakMap数据结构。

依赖就是reactive/ref返回的对象。而computed/watch等都通过一个函数参数消费依赖,这些函数参数就是所谓的更新。Composition API把依赖作为key,更新函数作为value来构建WeakMap,在依赖有变更时在WeakMap中找到对应的更新函数来执行,以此实现响应式。