vue渲染流水线由编译器、虚拟dom和渲染器协同构成:编译器将模板转为render函数,虚拟dom作为中间表示层实现按需更新,渲染器负责挂载与最小化dom操作。

渲染流水线不是一条单向直线,而是由编译器、虚拟 DOM 和渲染器三者紧密咬合的协同系统。Vue 的高效更新能力,正源于这三部分在不同时机各司其职又无缝衔接。
编译器:把模板变成可执行的 render 函数
你写的模板(比如 <div id="app">{{ msg }}</div>)不能直接运行,必须先经过编译器处理:
- 解析(parse):把模板字符串转成抽象语法树(AST),识别出标签、属性、插值、指令等结构;
- 优化(optimize):标记静态节点(如纯文本、无响应式绑定的元素),后续 diff 可跳过比对;
-
生成(codegen):把优化后的 AST 转为 JavaScript 渲染函数,例如:
return _c('div', { attrs: { "id": "app" } }, [_v(_s(msg))])。
这个函数就是整个渲染逻辑的“起点”,它每次执行都返回一棵新的虚拟 DOM 树。
虚拟 DOM:数据变化时的中间表示层
虚拟 DOM 不是真实节点,而是一个轻量级的 JavaScript 对象(VNode),描述了“应该长什么样”:
- 包含节点类型(
type)、属性(props)、子节点(children)、唯一标识(key)等关键字段; - 响应式数据变更时,会触发重新执行 render 函数,产出新 VNode;
- 旧 VNode 和新 VNode 进入 patch 阶段,只比对可能变化的部分(靠静态标记 + patch flag + key 驱动)。
它让 DOM 更新从“全量重写”变成“按需修补”,是性能和跨平台能力的基础。
渲染器:把 VNode 映射为真实 DOM
渲染器(runtime-core / runtime-dom)负责两件事:
-
首次挂载(mount):调用
patch(null, vnode),递归创建真实 DOM 元素并插入页面; - 更新比对(patch):对比新旧 VNode,复用已有节点、移动/删除/新增节点,最小化 DOM 操作;
- 内部封装了
h()(创建 VNode)、createApp()(初始化应用上下文)、renderer(统一渲染入口)等核心能力。
它屏蔽了平台差异,同一套 VNode 在浏览器、服务端、小程序中可被不同 renderer 解释执行。











