React & Vue 编译/运行流程

文章目录

  • 前言
    • [🧩 一、什么是编译阶段 vs 运行阶段?](#🧩 一、什么是编译阶段 vs 运行阶段?)
    • [🧠 二、React 的编译阶段(前端构建时)](#🧠 二、React 的编译阶段(前端构建时))
    • [⚙️ 三、React 的运行阶段(浏览器中)](#⚙️ 三、React 的运行阶段(浏览器中))
    • [🔁 Vue 的区别简析(对比 React)](#🔁 Vue 的区别简析(对比 React))
    • [✅ 总结:React 是否有编译 & 运行阶段?](#✅ 总结:React 是否有编译 & 运行阶段?)
      • [✅ 一句话总结](#✅ 一句话总结)
    • [📊 一、React vs Vue 编译 & 运行阶段对比图](#📊 一、React vs Vue 编译 & 运行阶段对比图)
    • [🧠 二、React Fiber 架构详解(运行时的核心)](#🧠 二、React Fiber 架构详解(运行时的核心))
      • [🎯 目标:](#🎯 目标:)
    • [🧱 1. 什么是 Fiber?](#🧱 1. 什么是 Fiber?)
    • [🔁 2. Fiber 渲染流程(可视化)](#🔁 2. Fiber 渲染流程(可视化))
      • [→ Fiber Tree 构建如下(树形结构):](#→ Fiber Tree 构建如下(树形结构):)
    • [⚙️ 3. Fiber 的调度阶段(分为两大阶段)](#⚙️ 3. Fiber 的调度阶段(分为两大阶段))
      • [Render Phase → 构建新 Fiber Tree](#Render Phase → 构建新 Fiber Tree)
      • [Commit Phase → 执行 DOM 变更](#Commit Phase → 执行 DOM 变更)
    • [⏱ 4. Fiber 的优先级调度模型(React 18+)](#⏱ 4. Fiber 的优先级调度模型(React 18+))
    • [🧪 5. 实际优化建议(使用 Fiber 正确姿势)](#🧪 5. 实际优化建议(使用 Fiber 正确姿势))
    • [✅ 总结一句话](#✅ 总结一句话)
  • 扩展:
    • [✅ 一、React Fiber 生命周期可视化流程图(文本版)](#✅ 一、React Fiber 生命周期可视化流程图(文本版))
    • [🔍 二、React Fiber Tree 控制台调试(自定义 Hook)](#🔍 二、React Fiber Tree 控制台调试(自定义 Hook))
    • [🧪 三、手写模拟 React.createElement → Fiber → DOM Demo(简化版)](#🧪 三、手写模拟 React.createElement → Fiber → DOM Demo(简化版))

前言

React 和 Vue 都有"编译阶段"和"运行阶段" 的概念,但它们的实现方式和目标略有不同,下面我们系统对比解释,并分析 React 的"编译 → 运行"过程。


🧩 一、什么是编译阶段 vs 运行阶段?

阶段 描述
编译阶段 将模板或 JSX 转换为可以执行的 JavaScript 结构(如虚拟 DOM)
运行阶段 执行渲染逻辑:生成 VDOM、比较 diff、更新真实 DOM、触发生命周期

🧠 二、React 的编译阶段(前端构建时)

步骤 说明
✅ JSX 编译 JSX 被 Babel 转换为 React.createElement(...)
✅ TS 转换 TypeScript 被编译为 JS
✅ 打包 使用 Vite/Webpack/Rollup 等构建工具将模块打包
✅ 可选优化 Tree-shaking、代码分割、Babel 插件优化(如 styled-components Babel 插件)

示例:

js 复制代码
// 编写
const el = <h1>Hello</h1>

// 编译后(Babel 做的)
const el = React.createElement('h1', null, 'Hello')

React 编译阶段主要发生在构建工具 + Babel 中,不涉及运行时模板编译(不像 Vue)


⚙️ 三、React 的运行阶段(浏览器中)

当 React 启动后,它进入运行阶段,包含以下核心步骤:

plaintext 复制代码
JSX → React.createElement() → React Element
        ↓
构建 Fiber Tree → Diff → Commit
        ↓
更新 DOM → 执行 useEffect → 渲染完成

具体包括:

步骤 对应机制
构建虚拟 DOM 调用 React.createElement
Fiber 架构调度 调和旧 Fiber 与新 Fiber,生成变更
DOM 操作 document.createElement / appendChild / setAttribute
生命周期执行 执行 useEffectuseLayoutEffect、组件函数体
异步并发调度(React 18) Scheduler + Lane 模型,实现优先级更新 & 中断恢复

🔁 Vue 的区别简析(对比 React)

项目 Vue(Composition / Template) React(JSX + Hooks)
编译阶段 模板 → render() 函数(Vue Compiler) JSX → React.createElement(Babel)
模板语法 模板语言(.vue SFC 模板) JavaScript/JSX(逻辑即模板)
模板静态提升 ✅ Vue 编译时标记静态节点优化 ❌ React 依赖开发者手动 memo/优化
运行时 创建 VNode → Patch → DOM 更新 创建 React Element → Fiber → DOM 更新

✅ 总结:React 是否有编译 & 运行阶段?

阶段 React 有吗? 特点
编译阶段 ✅ 有(靠 Babel、构建工具完成) JSX → createElement,不做模板编译
运行阶段 ✅ 有 React.createElement → Fiber → DOM
模板 AST 编译优化 ❌ 没有 Vue 特有的 Compiler-optimized 模板静态提升

✅ 一句话总结

React 的"编译阶段"更偏向 Babel 转换与打包构建,核心逻辑在"运行时"完成;而 Vue 则有独立的模板编译器,可在编译阶段做更多优化(如静态提升、指令转换)。


太好了!现在我们来深入 React 和 Vue 在编译阶段与运行阶段的对比图 + Fiber 调度机制讲解,帮助你构建对两大框架运行机制的系统认知。


📊 一、React vs Vue 编译 & 运行阶段对比图

plaintext 复制代码
╔═══════════════════════════╦════════════════════════════════════╗
║        Vue (SFC 模板)      ║          React (JSX)               ║
╠═══════════════════════════╬════════════════════════════════════╣
║【编译阶段】                ║【编译阶段】                         ║
║ .vue 模板 → Compiler AST  ║ JSX → Babel → createElement 调用   ║
║ AST → render 函数(VNode) ║ 类型检查 + 构建优化 + minify        ║
║ 静态节点优化(patch flag) ║ React 没有静态提升,靠 memo/useMemo║
╠═══════════════════════════╬════════════════════════════════════╣
║【运行阶段】                ║【运行阶段】                         ║
║ render() → 虚拟 DOM Tree   ║ JSX → React.createElement Tree     ║
║ VDOM Diff & Patch          ║ Fiber 架构:调和 + commit 阶段     ║
║ 生命周期 & 响应式绑定       ║ 函数组件 + Hooks(useEffect 等)    ║
║ 更新 DOM & 执行副作用       ║ 更新 DOM & 执行副作用               ║
╚═══════════════════════════╩════════════════════════════════════╝

🧠 二、React Fiber 架构详解(运行时的核心)

🎯 目标:

将 React 的渲染流程改为可中断、异步、优先级可调的调度模型。


🧱 1. 什么是 Fiber?

  • Fiber 是 React 16+ 的内部核心数据结构,用于描述组件树
  • 每个 Fiber Node 对应一个组件(或 DOM 节点)
  • React 会构建一个 Fiber Tree 来管理渲染/更新流程

🔁 2. Fiber 渲染流程(可视化)

plaintext 复制代码
function App() {
  return (
    <div>
      <Header />
      <Main />
    </div>
  )
}

→ Fiber Tree 构建如下(树形结构):

plaintext 复制代码
App
├── div
│   ├── Header
│   └── Main

每个节点是一个 FiberNode,包含:

ts 复制代码
{
  type: FunctionComponent | host,
  stateNode: 实例或DOM,
  child: FiberNode,
  sibling: FiberNode,
  return: FiberNode,
  alternate: 上一版本 FiberNode,
}

⚙️ 3. Fiber 的调度阶段(分为两大阶段)

阶段 作用
🔧 Render Phase 构建新 Fiber Tree,找出变化 → 可中断(异步)
📦 Commit Phase 应用 DOM 更新、执行副作用 → 同步执行

Render Phase → 构建新 Fiber Tree

plaintext 复制代码
每次更新:
- 创建新 Fiber Tree
- 与旧的 alternate 比较(diff)
- 标记哪些节点需要更新

Commit Phase → 执行 DOM 变更

plaintext 复制代码
- 统一处理 DOM 插入/删除/属性变更
- 执行 useEffect、useLayoutEffect
- 调用 ref 回调

⏱ 4. Fiber 的优先级调度模型(React 18+)

  • 使用 lane 模型 控制不同任务的优先级
  • 支持中断任务 → 插入高优先级任务 → 再恢复原任务

示例:输入框打字

plaintext 复制代码
输入内容时打字 → 高优先级(用户输入)
图片懒加载 → 低优先级(可延迟)

React 会自动控制调度顺序。


🧪 5. 实际优化建议(使用 Fiber 正确姿势)

场景 最佳实践
避免不必要更新 React.memo / useMemo / useCallback
异步加载 React.lazy + Suspense
重计算优化 useTransition(低优先级更新)
动画或高频交互 放入 useLayoutEffect / requestAnimationFrame
大型列表 react-window, react-virtualized

✅ 总结一句话

Vue 的模板编译更偏向"静态优化 +运行时模板解释 ",而 React 的 Fiber 架构则主打"异步调度 + 最小可中断工作单元 ",两者在编译运行路径上虽不同,但都为性能 + 可维护性 +响应效率服务。


扩展:


✅ 一、React Fiber 生命周期可视化流程图(文本版)

plaintext 复制代码
[App 组件函数执行]
        ↓
[React.createElement()]
        ↓
[构建 React Element Tree]
        ↓
[开始构建 Fiber Tree]
        ↓
╔═════════════════════════════════════╗
║ Render Phase(可中断)             ║
║ - 构建新 Fiber 节点                 ║
║ - 与旧 Fiber 比对                   ║
║ - 标记变化(placement、update)     ║
╚═════════════════════════════════════╝
        ↓
╔═════════════════════════════════════╗
║ Commit Phase(同步)                ║
║ - 应用真实 DOM 变更(append/remove)║
║ - 执行 useEffect / ref 回调         ║
╚═════════════════════════════════════╝
        ↓
[页面展示 & 等待用户交互]

🔍 二、React Fiber Tree 控制台调试(自定义 Hook)

可以用以下 hook 来"打印当前组件树结构",模拟观察 Fiber Tree 中的结构关系(开发环境中有用):

ts 复制代码
import { useEffect } from 'react'

export function useDebugFiber(name: string) {
  useEffect(() => {
    console.log(`[Fiber] ${name} mounted`)
    return () => {
      console.log(`[Fiber] ${name} unmounted`)
    }
  }, [])

  console.log(`[Fiber] ${name} rendering`)
}

使用方式:

ts 复制代码
function Child() {
  useDebugFiber('Child')
  return <div>child</div>
}

你会看到:

复制代码
[Fiber] Child rendering
[Fiber] Child mounted
...
[Fiber] Child unmounted

🧪 三、手写模拟 React.createElement → Fiber → DOM Demo(简化版)

这里我们模拟 React 渲染过程(不含调度,仅结构映射):

js 复制代码
// 模拟 JSX 编译产物
const element = {
  type: 'div',
  props: {
    id: 'root',
    children: [
      { type: 'h1', props: { children: 'Hello' } },
      { type: 'p', props: { children: 'World' } }
    ]
  }
}

// 模拟 Fiber 渲染为真实 DOM
function render(vnode, container) {
  const el = document.createElement(vnode.type)

  // 处理 props
  for (const key in vnode.props) {
    if (key === 'children') continue
    el.setAttribute(key, vnode.props[key])
  }

  // 递归处理子节点
  const children = vnode.props.children || []
  children.forEach(child => {
    if (typeof child === 'string') {
      el.appendChild(document.createTextNode(child))
    } else {
      render(child, el)
    }
  })

  container.appendChild(el)
}

// 使用
render(element, document.body)

输出:

html 复制代码
<body>
  <div id="root">
    <h1>Hello</h1>
    <p>World</p>
  </div>
</body>

相关推荐
passerby606117 分钟前
完成前端时间处理的另一块版图
前端·github·web components
掘了24 分钟前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅27 分钟前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment1 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税2 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore