2026-07-22 12:51:28
React 调度系统的核心是通过优先级机制解决任务饥饿问题,主要分为 CPU 调度、IO 调度和事件调度三个维度,其目标是平衡浏览器行为、框架逻辑和用户交互的优先级冲突。
一、CPU 调度:时间切片与宏任务CPU 调度的核心目标是解决 JavaScript 执行阻塞 UI 渲染的问题,通过时间切片(Time Slicing)将高耗时的 reconcile(协调)过程拆分为多个宏任务执行。
优先级划分
高优先级:浏览器原生行为(如点击、输入等),需立即响应。
低优先级:React 的 reconcile 逻辑(如虚拟 DOM 更新),通过宏任务分片执行。
宏任务特性:每个宏任务在浏览器行为(如重绘、回流)后执行,且仅执行一次,避免长时间阻塞主线程。
时间切片实现React 使用 MessageChannel 或 setTimeout 实现宏任务队列,将 reconcile 任务拆分为多个小任务,在浏览器空闲时逐步执行。例如:
// 伪代码:时间切片调度逻辑function scheduleTask(task) { let startTime = Date.now(); function workLoop() { while (Date.now() - startTime < 16) { // 16ms 帧预算 if (task.next()) break; // 任务未完成则继续 } if (task.next()) { requestIdleCallback(workLoop); // 下一帧继续 } } requestIdleCallback(workLoop);}解决饥饿问题高优先级任务(如用户输入)会中断低优先级的 reconcile 任务,确保交互流畅性。例如,在输入时,React 会暂停正在执行的更新任务,优先处理输入事件。

IO 调度的核心目标是解决数据加载(如网络请求)阻塞 reconcile 和 UI 渲染的问题,通过 lane 模型实现优先级叠加和动态调整。
Suspense 的优先级
低优先级:Suspense 组件在数据加载期间会显示 fallback 内容,其更新优先级低于普通 UI 更新。
优先级降低:在 Suspense 内部的 setState 会被标记为更低优先级,避免阻塞关键渲染路径。
Lane 模型
优先级分组:每个更新被分配一个或多个 lane(优先级通道),例如:
SyncLane:同步更新(最高优先级)。
InputDiscreteLane:用户输入相关更新。
TransitionLane:过渡动画相关更新(低优先级)。
优先级叠加:一个更新可以同时属于多个 lane,例如一个按钮点击可能同时触发 SyncLane 和 InputDiscreteLane。
动态调整React 根据任务依赖关系动态调整优先级。例如:
当 Suspense 数据加载完成时,相关更新的优先级会被提升,立即触发渲染。
如果高优先级任务(如用户输入)到来,低优先级的 IO 任务会被暂停。
事件调度的核心目标是根据事件类型分配不同优先级,优化用户交互体验。
高优先级事件
输入类事件:如 input、click、keydown,需要立即响应,标记为 DiscreteEvent(离散事件)。
实现方式:React 通过事件合成(Event Delegation)将原生事件转换为合成事件,在派发阶段根据事件类型分配优先级。
低优先级事件
连续类事件:如 scroll、touchmove、mousemove,允许减帧处理(如从 60fps 降至 30fps),标记为 ContinuousEvent(连续事件)。
防抖优化:用户可通过防抖(Debounce)或节流(Throttle)进一步优化性能,例如:
// 用户层防抖示例function debounce(fn, delay) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); };}window.addEventListener('scroll', debounce(handleScroll, 100));事件合成机制React 在事件派发阶段遍历所有事件监听器,根据事件类型生成不同优先级的更新任务。例如:
// 伪代码:事件合成与优先级分配function dispatchEvent(event) { const eventType = classifyEventType(event); // 分类事件类型 const priority = getPriorityByEventType(eventType); // 获取优先级 scheduleUpdate(priority, () => { // 执行对应更新 });}Fre 是 React 的轻量级替代方案,其调度系统设计更聚焦核心场景。
Fre 的核心调度
仅实现 CPU 和 IO 调度,不包含事件合成系统。
事件绑定为原生实现,依赖用户层防抖优化(如通过 debounce 手动控制频率)。
优势:体积小(1kb 左右),适合资源受限环境。
React 的全量调度
包含 CPU、IO 和事件调度,覆盖所有交互场景。
事件合成系统自动处理优先级分类,但增加了代码复杂度(React 源码中 90% 为非核心逻辑)。
阅读 React 源码时,建议忽略实现细节,聚焦以下问题:
总结:React 调度系统的本质是通过优先级机制平衡不同任务对主线程的竞争,其设计哲学是“核心调度不可替代,事件调度可用户优化”。理解这一点后,可更高效地阅读源码或设计类似系统(如 Fre)。