Skip to main content

Vue 3 与 Vue 2 的区别

一、Vue3 的优势

1、速度更快

  • Diff 算法优化
  • 静态提升
  • 事件监听缓存
  • SSR 服务端渲染优化

2、体积更小

通过 Tree-shaking,可以仅打包需要的模块,减小打包出来的体积。

3、写法更友好

  • Composition API(逻辑组织 + 逻辑复用)
  • TypeScript 支持
  • 使用 Proxy 重写响应式系统

二、Vue3 性能提升的原理

1、Diff 算法优化

vue3 在 diff 算法中新增了静态标记(PatchFlag),只对比带有标记的节点:

<div>
<p>HelloWorld</p>
<p>{{msg}}</p>
</div>

另外静态标记定义了十几种类型,可以更精确地定位对比节点的类型:

export const enum PatchFlags {
// 动态的文本节点
TEXT = 1,

// 2 动态 class
CLASS = 1 << 1,

// 4 动态样式
STYLE = 1 << 2,

// 8 动态 props,不包括类名和样式
PROPS = 1 << 3,

// 16 动态的 key,当 key 变化时需要完整的 diff 算法做比较
FULL_PROPS = 1 << 4,

// 32 表示带有事件监听器的节点
HYDRATE_EVENTS = 1 << 5,

// 64 一个不会改变子节点顺序的 Fragment
STABLE_FRAGMENT = 1 << 6,

// 128 带有 key 属性的 Fragment
KEYED_FRAGMENT = 1 << 7,

// 256 子节点没有 key 的 Fragment
UNKEYED_FRAGMENT = 1 << 8,

// 512 只有非 props 需要 patch 的,比如 ref
NEED_PATCH = 1 << 9,

// 动态的插槽
DYNAMIC_SLOTS = 1 << 10,

// 内置的特殊 flag,表示静态节点,永远不会用于 Diff
HOISTED = -1,

// 内置的特殊 flag,指代差异算法
BAIL = -2,
}

2、静态提升

Vue3 中对不参与更新的元素,会做静态提升(hoistStatic),只被创建一次,在渲染时直接复用,避免了重复创建节点。

Vue 3 Template Explorer 中可以看到:

没有静态提升:

有静态提升:

可以看到,静态内容 _hoisted_1 被移置 render 函数外,每次渲染时只要取 _hoisted_1 即可;

同时 _hoisted_1 被打上了静态标记 -1,即上面的 HOISTED 特殊标志,表示永远不会用于 Diff。

3、事件监听缓存

默认情况下绑定的事件会被视为动态变量,所以每次更新视图时都会去追踪它的变化,而 Vue3 做了事件监听缓存(cacheHandler)优化,将事件缓存起来复用,提升性能。效果如下:

未开启事件监听缓存:

开启事件监听缓存:

可以看到,开启事件监听缓存后,编译后的代码没有静态标记,也就表明 div 标签不再被追踪比较变化,进而提升性能。

4、SSR 服务端渲染优化

使用 SSR 服务端渲染开发时,Vue3 会将静态标签直接转为文本,提升性能。效果如下:

没有 SSR 优化:

有 SSR 优化: