Vue.js 3.0 对比 Vue 2

1、Vue 3.0 性能提升主要是通过哪几方面体现的?

一.编译阶段

  • diff 算法优化
    vue3 在 diff 算法中相比 vue2 增加了静态标记
    关于这个静态标记,其作用是为了会发生变化的地方添加一个 flag 标记,下次发生变化的时候直接找该地方进行比较

  • 静态提升
    Vue3 中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用
    这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用

  • 事件监听缓存
    默认情况下绑定事件行为会被视为动态绑定,所以每次都会去追踪它的变化

  • SSR 优化
    当静态内容大到一定量级时候,会用 createStaticVNode 方法在客户端去生成一个 static node,这些静态 node,会被直接 innerHtml,就不需要创建对象,然后根据对象渲染

二.源码体积
相比 Vue2,Vue3 整体体积变小了,除了移出一些不常用的 API,再重要的是 Tree shanking
任何一个函数,如 ref、reavtived、computed 等,仅仅在用到的时候才打包,没用到的模块都被摇掉,打包的整体体积变小

三、响应式系统
vue2 中采用 defineProperty 来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加 getter 和 setter,实现响应式
vue3 采用 proxy 重写了响应式系统,因为 proxy 可以对整个对象进行监听,所以不需要深度遍历
可以监听动态属性的添加
可以监听到数组的索引和数组 length 属性
可以监听删除属性

2、Vue 3.0 所采用的 Composition Api 与 Vue 2.x 使用的 Options Api 有什么区别?

  • 在逻辑组织和逻辑复用方面,Composition API 是优于 Options API
  • Composition API 几乎是函数,会有更好的类型推断。
  • Composition API 对 tree-shaking 友好,代码也更容易压缩
  • Composition API 中见不到 this 的使用,减少了 this 指向不明的情况
  • 如果是小型组件,可以继续使用 Options API,也是十分友好的

3、Proxy 相对于 Object.defineProperty 有哪些优点?

  • Proxy 可以直接监听对象而非属性;
  • Proxy 可以直接监听数组的变化;
  • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
  • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;

4、Vue 3.0 在编译方面有哪些优化?

  • diff 算法优化
    vue3 在 diff 算法中相比 vue2 增加了静态标记
    关于这个静态标记,其作用是为了会发生变化的地方添加一个 flag 标记,下次发生变化的时候直接找该地方进行比较

  • 静态提升
    Vue3 中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用
    这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用

  • 事件监听缓存
    默认情况下绑定事件行为会被视为动态绑定,所以每次都会去追踪它的变化

  • SSR 优化
    当静态内容大到一定量级时候,会用 createStaticVNode 方法在客户端去生成一个 static node,这些静态 node,会被直接 innerHtml,就不需要创建对象,然后根据对象渲染

5、Vue.js 3.0 响应式系统的实现原理?

Vue3 使用 Proxy 对象重写响应式系统,这个系统主要有以下几个函数来组合完成的:

1、reactive:
接收一个参数,判断这参数是否是对象。不是对象则直接返回这个参数,不做响应式处理
创建拦截器对象 handler, 设置 get/set/deleteProperty
get
收集依赖(track)
返回当前 key 的值。
如果当前 key 的值是对象,则为当前 key 的对象创建拦截器 handler, 设置 get/set/deleteProperty
如果当前的 key 的值不是对象,则返回当前 key 的值
set
设置的新值和老值不相等时,更新为新值,并触发更新(trigger)
deleteProperty
当前对象有这个 key 的时候,删除这个 key 并触发更新(trigger)
返回 Proxy 对象
2、effect: 接收一个函数作为参数。作用是:访问响应式对象属性时去收集依赖
3、track:
接收两个参数:target 和 key
如果没有 activeEffect,则说明没有创建 effect 依赖
如果有 activeEffect,则去判断 WeakMap 集合中是否有 target 属性,
WeakMap 集合中没有 target 属性,则 set(target, (depsMap = new Map()))
WeakMap 集合中有 target 属性,则判断 target 属性的 map 值的 depsMap 中是否有 key 属性
depsMap 中没有 key 属性,则 set(key, (dep = new Set()))
depsMap 中有 key 属性,则添加这个 activeEffect
4、trigger:
判断 WeakMap 中是否有 target 属性
WeakMap 中没有 target 属性,则没有 target 相应的依赖
WeakMap 中有 target 属性,则判断 target 属性的 map 值中是否有 key 属性,有的话循环触发收集的 effect()

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容