Vue 3静态提升是编译阶段将纯静态节点及属性提取为常量VNode并缓存复用的优化,满足无插值、无指令、属性全字面量且子树全静态等条件,运行时直接引用、跳过创建与diff,显著减少内存分配和比对开销。

Vue 3 的静态提升不是运行时行为,而是编译阶段自动完成的“隐形加速器”:它把模板里完全不变的部分提前造好、存起来,后续所有渲染都直接复用,跳过重复创建和比对。
哪些内容会被提升?
必须同时满足以下条件,节点或属性才可能被提升:
- 是普通 HTML 元素(
<div>、<p>)或纯文本,不能是组件、v-if、v-for、插槽等动态容器 - 内部不含任何插值(
{{ }})、指令(v-)、事件绑定(@click)或动态属性(:id) - 所有属性值都是字符串字面量,比如
class="btn"✅,但:class="cls"❌;style="color:red"✅,而:style="{ color }"❌ - 整棵子树都静态——哪怕一个子节点含
{{ msg }},父节点就整个失去提升资格
静态属性也能单独提升
即使整个标签因含动态内容无法整体提升,它的静态属性仍会被抽出来缓存。例如:
<div :id="dynamicId" class="container" data-role="main">{{ content }}</div>
立即学习“前端免费学习笔记(深入)”;
编译器会提取出:const _hoisted_1 = { class: "container", "data-role": "main" }
渲染时通过 _mergeProps({ id: _ctx.dynamicId }, _hoisted_1) 合并使用,避免每次构造新 props 对象。
提升后怎么影响运行时?
生成的 render 函数中,静态部分彻底移出函数体:
- 在 setup 外部定义常量,如
const _hoisted_1 = /*#__PURE__*/_createVNode("h1", null, "标题", -1) - render 中不再调用
_createVNode创建它,而是直接引用_hoisted_1 - 该 VNode 的
PatchFlag设为-1(HOISTED),diff 阶段完全跳过比对
为什么真能提速?
核心是把开销从高频运行时,转移到一次性的编译期:
- VNode 创建次数大幅减少 → 内存分配压力下降 → GC 触发更少
- diff 过程跳过全部静态节点 → 比对路径缩短,尤其在页脚、头部、长列表等场景效果明显
- 多个组件实例可共享同一份静态 VNode 引用,节省内存



















