Vue3的优化
编译方面
diff方法优化
Vue3对于不参与更新的元素,做静态标记并提示,只会被创建一次,在渲染时直接复用。
vue2中的虚拟dom通过模板创建虚拟节点(js对象),然后使用虚拟节点跟上一次缓存的虚拟节点进行全量的对比。在vue3中做出了改进,在与上次虚拟节点进行对比时候,只对比带有patch flag的节点,并且可以通过flag的信息得知当前节点要对比的具体内容。
hoistStatic 静态提升
把静态的节点进行提升,所有的静态节点都被拿到了渲染函数体外面,也就是说在应用第一次的启动被创建了一次后,之后这些虚拟节点会在每次渲染时候被不停的复用,这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用。
cacheHandlers 事件侦听器缓存
在第一次渲染时会自动生成一个内联的函数,在内联函数里面引用当前的fn,然后把内联函数cache起来,后续的更新会从缓存中读同一个函数,因为是同一个函数,也就没有追踪变化的必要,这样就神奇的把这个span变成了静态的。手写的内联函数也会被cache起来,这样就会避免一些没必要的更新。
<span onClick={() => console.log()}></span>
变化侦测
在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
原理:
- ES6 Module引入进行静态分析,故而编译的时候正确判断到底加载了那些模块
- 静态分析程序流,判断那些模块和变量未被使用或者引用,进而删除对应代码
更好的 TypeScript 支持
Vue 3是用TypeScript编写的库,可以享受到自动的类型定义提示
Composition API
它以 setup 启动函数作为逻辑组织的入口,暴露了响应式 API 为用户所用,也提供了生命周期函数以及依赖注入的接口,就是将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去。
Composition API响应式的实现依靠一个保存有依赖与更新对应关系的WeakMap数据结构。这里的WeakMap数据结构指的就是ES6提供的WeakMap数据结构。
依赖就是reactive/ref返回的对象。而computed/watch等都通过一个函数参数消费依赖,这些函数参数就是所谓的更新。Composition API把依赖作为key,更新函数作为value来构建WeakMap,在依赖有变更时在WeakMap中找到对应的更新函数来执行,以此实现响应式。