Vue3 渲染原理
编译时:模板 → render 函数
开发者编写的 <template> 并不会直接在浏览器中执行。Vue3 会在构建阶段将模板编译成 render 函数,并在编译过程中完成两个关键优化:
静态提升(Static Hoisting):模板中不会变化的节点,比如 <h1>博客标题</h1> 这类没有插值表达式、动态属性和事件绑定的纯静态内容,会在编译时被提取为常量。组件重新渲染时,不需要重复创建这些节点。
Patch Flag(补丁标记):编译器会为动态节点标记变化类型,告诉运行时“这个节点的哪些部分可能变化”。比如 <p :class="cls"></p> 会被标记为 CLASS + TEXT。Diff 时只比较这些被标记的部分,静态内容可以直接跳过。
运行时:虚拟 DOM
初次渲染时,执行 render 函数生成虚拟 DOM 树,然后调用原生 DOM API 逐一创建真实元素,挂载到 #app 上。
同时进行依赖收集:当模板里引用了 count.value 时,触发 Proxy 的 get 拦截。Vue3 的依赖收集最小单位是组件——不是单个变量,而是一个组件对应一个副作用函数。
响应式更新:精准触达
当 count.value 改变时,触发 Proxy 的 set 拦截。Vue3 能定位到依赖该数据的组件,然后重新执行对应组件的 render 函数,生成一棵新的虚拟 DOM 树。
新树和旧树进行 Diff,结合编译阶段的 Patch Flag,Vue3 只更新真正变动了的 DOM 节点,静态节点完全跳过。
渲染流程串联
写模板 → 编译(静态提升+Patch Flag) → render函数 → 虚拟DOM → 真实DOM
↑
响应式数据变化 → set拦截 → 找到依赖组件 → 重新render → Diff → 精准DOM更新