静态内容提升是vue 3编译器将纯静态节点(如无指令、无插值、无动态属性的元素及文本)提前创建为常量vnode并缓存复用,以减少运行时vnode创建、内存分配与diff比对开销。

静态内容提升(Static Hoisting)是 Vue 3 在编译阶段自动完成的一项关键优化,它把模板中“永远不变”的部分提前创建并缓存,运行时直接复用,从而跳过重复的 VNode 构造、减少内存分配、降低 GC 压力。
哪些内容会被提升?
不是“看起来静态”就能被提升,而是必须满足严格的常量性判定:
- 节点类型为普通元素(
<div>、<code><p></p>)或纯文本,不能是组件、v-for、v-if、v-slot等动态容器 - 节点内不含任何插值(
{{ }})、指令(v-)、动态绑定(:id、@click) - 所有属性值本身也得是字面量:比如
class="btn"✅,但:class="cls"❌;style="color:red"✅,而:style="{ color }"❌ - 整棵子树都必须静态:哪怕一个子节点含
{{ msg }},其父节点就整体失去提升资格 - 例如
<div :id="dynamicId" class="container" data-role="main">{{ content }}</div> - 编译器会提取出
{ class: "container", "data-role": "main" }并缓存为_hoisted_1 - 渲染时通过
_mergeProps({ id: _ctx.dynamicId }, _hoisted_1)合并使用,避免每次构造新 props 对象 - 静态节点被移出 render,定义在 setup 外部,如
const _hoisted_1 = /*#__PURE__*/_createVNode("h1", null, "标题", -1) - render 中不再调用
_createVNode创建它,而是直接引用_hoisted_1 - 其 PatchFlag 被设为
-1(HOISTED),diff 阶段完全跳过比对 - 首屏渲染多一次对象创建,但后续所有更新都省掉这部分开销
- VNode 创建减少 → 内存分配减少 → GC 触发频率下降
- diff 跳过静态节点 → 比对路径大幅缩短,尤其对长列表、复杂页脚等场景效果显著
提升不只是整块节点,还包括属性分离
即使整个标签因含动态内容无法整体提升,它的静态属性仍可被单独提取:
提升后怎么影响运行时?
提升结果直接反映在生成的 render 函数中:
它为什么能真正提速?
核心在于把运行时开销前置到编译期解决:










