当前位置: 首页 > backend >正文

React Vue 编译/运行流程

文章目录

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

示例:

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

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


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

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

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 编译 & 运行阶段对比图

╔═══════════════════════════╦════════════════════════════════════╗
║        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 渲染流程(可视化)

function App() {return (<div><Header /><Main /></div>)
}

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

App
├── div
│   ├── Header
│   └── Main

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

{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

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

Commit Phase → 执行 DOM 变更

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

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

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

示例:输入框打字

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

React 会自动控制调度顺序。


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

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

✅ 总结一句话

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


扩展:


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

[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 中的结构关系(开发环境中有用):

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`)
}

使用方式:

function Child() {useDebugFiber('Child')return <div>child</div>
}

你会看到:

[Fiber] Child rendering
[Fiber] Child mounted
...
[Fiber] Child unmounted

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

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

// 模拟 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)// 处理 propsfor (const key in vnode.props) {if (key === 'children') continueel.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)

输出:

<body><div id="root"><h1>Hello</h1><p>World</p></div>
</body>

http://www.xdnf.cn/news/13469.html

相关文章:

  • 入门Scikit-learn:让机器学习像呼吸一样自然!
  • thinkphp 一个系统在同一个域名下,一个文件夹下如何区分多站点——穷人的精致规划——仙盟创梦IDE
  • 开疆智能ModbusTCP转Canopen网关连接三菱FX5u配置案例
  • 解决idea创建SpringBoot项目,会自动创建.git文件导致commit两极分化的现象。
  • 软件测试之基于博客系统项目的功能测试
  • OpenAI推出o3-Pro模型
  • Weblogic 弱口令-任意文件读取
  • 【uniapp】小程序中input输入框的placeholder-class不生效
  • 【慧游鲁博】【11】后端 · Spring Boot 集成 Python 配置
  • 跨链/Layer2交易所架构:全链互操作与ZK-Rollup优化
  • 快速上手驭码CodeRider二
  • 【VBA】把目录及子目录下所有doc/docx转换为pdf格式
  • 【一文理解】下采样与上采样区别
  • DAY 27 函数专题2:装饰器
  • 3.2 组帧
  • 嵌入式学习笔记DAY35(数据库)
  • 少量数据达到更好效果
  • 跌穿20万辆,更猛烈的价格战却导致销量暴跌,难怪电车内讧了!
  • 基于OpenCV的滑动验证码缺口识别全流程解析(2025企业级方案)
  • 基于强化学习的智能调度系统:从理论到实践
  • VSomeip库- 编译使用
  • Dify-6: 部署
  • HTB 赛季8靶场 - TombWatcher
  • 制造业数智化转型:从行业痛点到R²AIN SUITE AI一体化解决方案
  • 算法题(166):占卜DIY
  • 打造多模态交互新范式|彩讯股份中标2025年中国移动和留言平台AI智能体研发项目
  • antd-vue - - - - - a-table排序
  • 【模板编程】
  • GPU架构对大模型推理部署到底有什么影响?
  • 跨平台架构区别