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

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>

相关文章:

  • 11. 线性表的顺序表示和实现(3)
  • 新闻类鸿蒙应用全链路测试实践:性能、兼容性与体验的深度优化
  • 【多模态/T5】[特殊字符] 为什么视频生成模型还在用T5?聊聊模型选择的学问
  • 中兴B860AV1.1江苏移动-自动降级包
  • Spring MVC完全指南 - 从入门到精通
  • 电路板的 “双面绣”:猎板双色油墨如何重塑电子制造新范式
  • 线 性 数 据 结 构 双 雄:栈 与 队 列 的 原 理、实 现 与 应 用
  • HDFS 异构存储及存储策略
  • 《Linux C编程实战》笔记番外:如何避免子进程成为僵尸进程
  • 每日Prompt:人像写真
  • uni-app bitmap.load() 返回 code=-100
  • xilinx的gt的ALIGN_COMMA_WORD设置的作用
  • 鸿蒙新闻应用全链路优化实践:从内核重构到体验革新
  • 实时获取印度国家股票数据 API 实操
  • Explore Image Deblurring via Encoded Blur Kernel Space论文阅读
  • AIStor 的模型上下文协议 (MCP) 服务器: 工作原理
  • [Git] 配置 Git
  • 3D IC(立体集成电路)的生态机会
  • 多项目资源如何高效配置与再分配?
  • 【JavaAPI搜索引擎】项目测试报告
  • 10m网站并发量/电子商务网站建设论文
  • 有哪些网站可以做兼职/推广文章的推广渠道
  • 公司常用网站开发软件/推广引流渠道有哪些
  • 网站谁家做得好/可以免费发广告的网站
  • 旅游网站前台怎么做/搜索网站关键词
  • 大连百度推广seo/深圳网站seo推广