静态提升是vue3编译时将纯静态节点(无插值、指令、动态属性)提取为常量vnode缓存复用的优化策略,提升渲染性能。

Vue3 的静态提升(Static Hoisting)是一种编译时优化策略,它把模板中不随响应式数据变化的静态节点提前创建为 VNode 并缓存,避免每次渲染都重复创建,从而减少运行时开销、提升首屏和更新性能。
哪些内容会被静态提升?
Vue 编译器会识别出模板中完全静态的部分——即不含任何插值、指令、动态属性或组件绑定的节点。例如:
- 纯文本节点:
<div>Hello World</div> - 静态标签结构:
<header><h1>Title</h1></header> - 带静态 class/style 的元素:
<button class="btn" style="color: red">Click</button>
只要节点内部没有 {{ }}、v-if、v-for、:id、@click 等动态特征,它就可能被提升。
静态提升是怎么工作的?
在编译阶段,Vue3 的模板编译器(@vue/compiler-dom)会扫描 AST,把可提升的静态节点提取出来,在组件的 setup 函数外部 创建一次 VNode,并赋值给一个常量(如 _hoisted_1)。后续每次渲染,直接复用这个已创建好的 VNode 对象,跳过 createElement 调用。
比如这段模板:
Welcome
This is a static paragraph.
审查 Vue 管理后台的变更请求(Vue 2 + Element UI,Vue 3 + Element Plus)。重点关注最小化变更实现、上线风险检查以及回归检查清单生成。
{{ message }}
编译后,前两个子节点(<h1></h1> 和 <p></p>)会被提升,只有 <span></span> 随 message 动态生成。
如何验证是否发生了静态提升?
最直接的方式是查看编译后的 JavaScript 输出:
- 使用 Vue Template Explorer 粘贴模板,观察生成代码中是否有
const _hoisted_1 = ...这类声明 - 在 Vite 项目中启用
build.rollupOptions.output.manualChunks或使用vue-tsc --noEmit --declaration配合源码调试 - 在 DevTools 的 “Sources” 面板中搜索
_hoisted,定位到组件 render 函数附近
注意:开启 dev 模式时,为了便于调试,部分提升可能被禁用;生产构建(mode: 'production')下才 fully 启用。
什么情况下静态提升会失效?
即使看起来“静态”,只要存在以下任一情况,节点就无法被提升:
- 父元素有动态绑定(如
<div :class="cls">...</div>,整个子树降级为动态) - 节点自身含空格/换行以外的动态内容(例如
<span>{{ '' }}</span>或<div v-show="false">) <li>使用了自定义指令(哪怕没参数)、<code>v-html、v-text - 作为
<slot></slot>默认内容且父组件可能传入作用域插槽
小技巧:如果想强制提升某段结构,可把它抽成计算属性返回 HTML 字符串(不推荐),或用 <template v-is="'static-wrapper'"></template> + 自定义渲染函数(高级用法,需谨慎)。









