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 优化: