Vue 模板编译流程
完整流水线
一段模板字符串最终变成页面上的真实 DOM,Vue 内部通常会经过六个阶段:
模板字符串 → AST → 标记静态节点 → render 函数 → 虚拟 DOM → 真实 DOM每一步做了什么
1. 模板 → AST(抽象语法树)
编译器用正则+状态机解析模板,把 <div><p></p></div> 转成一棵树状结构。每个节点记录自己的标签名、属性、子节点、指令等信息。
2. AST → 优化标记
Vue3 会在这一步遍历 AST,标记出哪些节点是纯静态的(没有 、没有 v-if、没有 :class 等动态绑定)。这些节点在后续 Diff 阶段可以直接跳过,从而减少运行时比较成本。
3. AST → render 函数
把优化后的 AST 转成一串 JS 函数调用,比如 h('div', null, [h('p', null, ctx.msg)])。这就是 render 函数的本体。
4. render 函数 → 虚拟 DOM
组件初始化或更新时会执行 render 函数,返回一棵虚拟 DOM 树。虚拟 DOM 本质上是轻量级 JavaScript 对象,用来描述页面结构和节点状态。
5. 虚拟 DOM → 真实 DOM
首次渲染时,遍历虚拟 DOM 树,调用 document.createElement、element.setAttribute 等原生 API,生成真实节点,挂载到容器上。
6. 更新时:Diff → Patch
数据变化后,render 会重新执行并生成新的虚拟 DOM 树。新旧两棵树通过 Diff 算法比较(Vue3 在数组子节点更新中使用双端对比和最长递增子序列),计算出尽可能少的 DOM 更新操作,只修改实际变化的部分。
编译阶段承担静态分析
核心思路是将能够在构建阶段确定的信息提前分析并固化下来,运行时就可以减少不必要的计算。静态节点在编译阶段被识别后,运行时无需再次逐个比对,这也是 Vue3 相比 Vue2 在更新性能上更有优势的重要原因之一。