loading

vue3的改进

# 响应式

  • vue 2.x 内部是通过 Object.defineProperty 这个 API 去劫持数据的 getter 和 setter 来实现响应式的。这个 API 有一些缺陷,它必须预先知道要拦截的 key 是什么,所以它并不能检测对象属性的添加和删除。

  • Vue.js 3.0 使用了 Proxy API 做数据劫持,它劫持的是整个对象,自然对于对象的属性的增加和删除都能检测到。 响应式是惰性的

  • 在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它内部深层次的变化,就需要递归遍历这个对象,执行 Object.defineProperty 把每一层对象数据都变成响应式的,这无疑会有很大的性能消耗。

  • 在 Vue.js 3.0 中,使用 Proxy API 并不能监听到对象内部深层次的属性变化,因此它的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部属性才会变成响应式,简单的可以说是按需实现响应式,就没有那么大的性能消耗。

# TypeScript

Vue3是基于typeScript编写的,提供了更好的类型检查,能支持复杂的类型推导

# 更小

# tree-shaking

与Vue2相比较,Vue3整体体积变小了,移除了一些比较冷门的feature:如 keyCode 支持作为 v-on 的修饰符、on、off 和 $once 实例方法、filter过滤、内联模板等。tree-shaking 依赖 ES2015 模块语法的静态结构(即 import 和 export),通过编译阶段的静态分析,找到没有引入的模块并打上标记。任何一个函数,如ref、reavtived、computed等,仅仅在用到的时候才打包,没用到的模块都被摇掉,打包的整体体积变小。

# 更快

# diff算法优化

Vue2中的虚拟dom是进行全量对比,Vue3新增了静态标记。静态标记值为 -1 ,特殊标志是负整数表示永远不会用于 Diff,在与上次虚拟节点进行比较的时候,只对比带有静态标记为1的节点,并且可以通过标记的信息得知当前节点对比的具体内容。

# 静态提升

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

# 事件监听缓存

在vue2中创建一个虚拟节点button,属性里面多了一个事件onclick,内容就是count++。在vue3中会认为这里的事件处理是不会变化的,不是说这次渲染是事件函数,下次就变成别的,于是vue3会智能地发现这一点,会做缓存处理,它首先会看一看缓存里面有没有这个事件函数,有的话直接返回,没有的话就直接赋值为一个count++函数,保证事件处理函数只生成一次。

# 预字符串化

vue2对于模板的处理是解析器parseHTML,通过标记和不断循环生成一个带有type、tag、attrsList、children等属性的对象,所以生成的vnode实际上是一棵包含了静态和动态的巨大树。

vue3对于静态节点会处理成字符串,该优化在ssr下的性能提升尤为明显。值得注意的是,目前vue3只会对连续的静态节点才会预字符串化,在版本3.2.31当连续静态标签为5个时可以触发预字符串化。

# SSR优化

当有大量静态内容时,这些内容会被当成纯字符串推进一个buffer里面,即使存在动态的绑定,会通过插值嵌入进去。这样会比通过虚拟dom来渲染快很多。当静态内容大到一定量级的时候,会用_createStaticVNode方法在在客户端去生成一个static node,这些静态node会被直接innerHTML,就不需要创建对象,然后直接根据对象渲染。

# 其他

  • Custom Renderer API:暴露了自定义渲染API、
  • Fragment,Teleport(Protal),Suspense:更先进的组件
  • 模板可以写多个根节点
  • Proxy 代替 object.defineProperty()
  • 可以在样式中使用 script 中定义的变量
最近更新时间: 2022/09/28 16:26:36
最近更新
01
2023/07/03 00:00:00
02
2023/04/22 00:00:00
03
2023/02/16 00:00:00