React19 渲染流程

一、React 渲染架构

底层渲染流程大致可以分为两大阶段:render 阶段(Scheduler -> Reconciler)、commit 阶段(Renderer)

注意这里的 render 阶段和 Renderer 渲染器是两个东西!!!

主要的阶段可以总结为两个公式:

JavaScript 复制代码
const state = reconcile(update); // 通过 reconciler 计算出最新的状态
const UI = commit(state); // 通过最新的 state 渲染出 UI

二、调度器(Scheduler):渲染的入口与优先级控制

Scheduler 类似于浏览器的原生 API requestIdleCallback。React 团队没有使用 requestIdleCallback 是因为考虑为兼容性问题。

Scheduler 是整个渲染执行链条的入口,负责:

  1. 将变更转化为任务
  2. 按优先级调度任务执行
  3. 支持时间切片与可中断渲染

虽然每一帧绘制时间约为 16.66ms,但是如果屏幕没有刷新,那么浏览器会安排长度为 50ms 左右的空闲时间。

研究表明,用户操作之后,100ms 以内的响应给用户的感觉都是瞬间发生,也就是说不会感受到延迟感,因此将空闲时间设置为 50,浏览器依然还剩下 50ms 可以处理用户的操作响应,不会让用户感到延迟,这就是我们面试题中常看到的浏览器渲染每帧的空闲时间。

更新任务被排队

当你调用 setStatedispatchstartTransition、事件触发更新时,React 内部会:

Plain 复制代码
scheduleUpdateOnFiber(fiber, lane, eventTime)

这个函数是调度入口,它将更新附着在对应的 Fiber 上,并根据任务的 lane(内部优先级) 更新任务队列。

任务优先级系统(Lanes)

React 内部并不使用单一队列,而是用多 lane 机制。

优先级由 Scheduler 根据事件来源与延迟(expiration time)决定。

时间切片(Time Slicing)

Scheduler 会根据浏览器的空闲时间,决定是在当前帧继续执行还是 yield 给浏览器,这样协调器起点也是不同的:

  • performSyncWorkOnRoot(同步更新流程)
  • performConcurrentWorkOnRoot(并发更新流程)
JavaScript 复制代码
// performSyncWorkOnRoot 会执行该方法
function workLoopSync(){
  while(workInProgress !== null){
    performUnitOfWork(workInProgress)
  }
}
// performConcurrentWorkOnRoot 会执行该方法
function workLoopConcurrent() {
  // shouldYield 表明任务是否可以中断
  // 如果 workInProgress 为 null,说明已经没有下一个 FiberNode,也就是说明整颗 Fiber tree 树构建完毕
  while (workInProgress !== null && !shouldYield()) {
    // performUnitOfWork创建下一个 FiberNode,并且将已创建的 FiberNode 连接起来(child、return、sibling),形成一个链表结构的 Fiber tree
    workInProgress = performUnitOfWork(workInProgress); 
  }
}

shouldYield 判断当前帧是否该让出,避免阻塞主线程。

中断 + 恢复机制

如果有更高优先级的任务,中断当前 render,后续在合适时机 ​恢复执行​。这样能确保交互响应不会被大更新阻塞。

三、协调器(Reconciler):Fiber 树的 diff 与标记

协调器的核心任务是:

  1. 对比新旧树,确定哪些节点变化
  2. 生成 workInProgress Fiber 树
  3. 标记变化(Placement、Update、Deletion)
  4. 不直接修改 DOM,而是将变化收集起来

Fiber 数据结构

每一个组件在运行时都有一个 Fiber 节点:

  • 指向真实 DOM 实例
  • 链接 child / sibling / return 三个方向
  • 记录当前组件状态、props、更新队列、优先级等属性

这种结构不同于简单递归栈,它更像一颗​可分片执行的链表树​。

Reconciler 工作循环 ------ render 阶段

协调器是由 Scheduler 调度后执行的。React 会从 Root Fiber 开始 traverse。

a. beginWork

处理当前节点逻辑,根据类型(函数组件 / 类组件 / Fragment 等)判断需要构建哪些子 Fiber。

b. completeWork

在子节点构建完成后整合变化,把节点的更改标记写入 flags

JavaScript 复制代码
// 深度优先遍历
function performUnitOfWork(fiberNode){
  // 省略 beginWork 
  if(fiberNode.child){
    performUnitOfWork(fiberNode.child);
  }
  // 省略 CompleteWork 
  if(fiberNode.sibling){
    performUnitOfWork(fiberNode.sibling);
  }
}

整个过程构成一个 ​双缓冲机制​:

  • current Fiber(当前渲染状态)
  • workInProgress Fiber(正在构建的树)

最终 workInProgress 树会用于提交阶段。

标记变化

协调器不会直接操作 DOM,而是根据差异为每个节点打上 flags:

  • Placement:新节点插入
  • Update:属性/文本内容更新
  • Deletion:删除节点

这些标记会在提交阶段被 Renderer 读取。

四、渲染器(Renderer):真实环境应用变化

Renderer 是把协调阶段生成的变化同步应用到最终环境,比如:

  • 浏览器的 DOM
  • React Native 原生视图
  • 其他自定义渲染平台

React 通过隔离平台实现了 Renderer 的可插拔。相较于 render 阶段,此时 commit 阶段不可中断恢复。

提交阶段的三个子阶段

协调阶段完成后进入 ​commit 阶段​:

a. Before Mutation

执行 getSnapshotBeforeUpdate(类组件),记录焦点、selection(输入框光标)等。

JavaScript 复制代码
commitBeforeMutationEffects(root, finishedWork)
// 读取旧的 DOM 状态
b. Mutation

真实 DOM 操作发生位置 ​,根据 flags 做:appendChild、removeChild、update 属性、插入节点等。

然后切换 Fiber Tree(也就是上面提到的双缓冲机制,两棵树互换)。

c. Layout

useLayoutEffect 的意义是:在 DOM 更新完成后,浏览器绘制之前,同步读取或修改布局。

执行 useLayoutEffect、componentDidMount、componentDidUpdate 的回调。

注意哦!!!这里虽然 DOM 已经变更了,但是浏览器页面​还没有 paint,下一步才是绘制​。

渲染器应用 DOM 改变

JavaScript 复制代码
commitUpdate(domElement, updatePayload, type, oldProps, newProps)
// 调用一系列 DOM API 为元素属性更新赋值

这里 paint 之后,才会执行 useEffect(异步)的回调。

所以如果需要操作 DOM ,要在 useLayoutEffect 钩子执行。

相关推荐
西门吹-禅1 小时前
react native --Expo---Android 开发
javascript·react native·react.js
我是伪码农1 小时前
Vue 1.29
前端·javascript·vue.js
css趣多多1 小时前
Vue动态组件以及keep-alive的使用
前端·javascript·vue.js
盐真卿1 小时前
python第五部分:文件操作
前端·数据库·python
天空属于哈夫克31 小时前
企微自动化控制台:跨语言调用与多进程管理的技术架构
架构·自动化·企业微信
晚霞的不甘2 小时前
Flutter for OpenHarmony《智慧字典》英语学习模块代码深度解析:从数据模型到交互体验
前端·学习·flutter·搜索引擎·前端框架·交互
摘星编程2 小时前
React Native + OpenHarmony:自定义useLanguage语言切换
javascript·react native·react.js
小邓睡不饱耶2 小时前
Hadoop:从架构原理到企业级实战,大数据处理入门到精通
大数据·hadoop·架构
子春一2 小时前
Flutter for OpenHarmony:构建一个优雅的 Flutter 每日一句应用,深入解析状态管理、日期驱动内容与 Material 3 交互动效
javascript·flutter·交互