Skip to content

Vue3 编译优化

什么是"编译"

在 Vue 中,“编译”指的是模板语法(<template>)在构建阶段被转换为 render 函数的过程。这个转换通常在打包阶段完成,不会占用浏览器运行时的主要执行流程。

三大编译优化

静态提升(Static Hoisting)

模板中不会变化的内容,例如没有 、没有 :class="xxx"、没有 @click 的纯静态节点,会在编译阶段被提升到 render 函数外部并保存为常量。组件每次更新时无需重新创建这些节点,可以直接复用已提升的静态节点。

js
// 编译前
<div>
  <h1>这是静态标题</h1>
  <p>{{ dynamicText }}</p>
</div>

// 编译后(简化示意)
const _hoisted_1 = h('h1', null, '这是静态标题')  // 提到外面
function render() {
  return h('div', null, [_hoisted_1, h('p', null, ctx.dynamicText)])
}

Patch Flag(补丁标记)

每个动态节点都会被标记可能发生变化的类型,例如 TEXT(文本变化)、CLASS(class 变化)、STYLE(style 变化)、PROPS(属性变化)等。Diff 时只需要检查被标记的部分,无需进行完整的属性比对。

Block Tree(动态节点树)

Vue3 会将模板中的动态节点组织为独立的 Block Tree。组件更新时,运行时可以直接遍历动态节点集合,静态子树不参与 Diff。比如一个包含 100 个节点的页面,如果只有 3 个节点是动态的,Diff 的主要比较范围就可以收敛到这 3 个动态节点。

编译优化的共同目标

Vue3 的编译优化思路很统一:将能够在编译阶段确定的信息提前处理,运行时只处理必要的动态部分。静态提升负责提前创建稳定节点,Patch Flag 负责提前标记动态变化类型,Block Tree 负责提前组织动态节点范围。这些优化共同服务于一个目标:尽可能降低运行时 Diff 的工作量。