得鹿梦鱼 得鹿梦鱼

任务调度

React 的任务调度机制主要通过其内部的 Scheduler(调度器) 模块实现,目的是协调浏览器主线程的资源分配,确保高优先级任务(如用户交互、动画)能够及时响应,同时避免低优先级任务(如数据预加载、非紧急渲染)阻塞主线程

Fiber 架构引入了任务调度机制,将渲染过程分解为多个小任务单元。React 使用 时间切片(Time Slicing) 技术,将任务分配到浏览器的空闲时间执行,从而避免长时间占用主线程

优先级模型

在React中,任务优先级是一个核心概念,尤其是在React的并发模式(Concurrent Mode)中。任务优先级决定了React如何调度和更新UI,以确保用户体验的流畅性和响应性。

同步优先级(ImmediatePriority)

优先级值: 1
描述: 这是最高优先级,用于需要立即执行的任务。通常用于用户交互、动画等需要即时响应的场景。
使用场景: 用户点击、输入等需要立即反馈的操作

用户阻塞优先级(UserBlockingPriority)

优先级值: 2
描述: 这个优先级用于用户交互相关的任务,虽然不是立即执行,但需要尽快处理,以避免用户感受到延迟。
使用场景: 用户输入、按钮点击等需要快速响应的操作

普通优先级(NormalPriority)

优先级值: 3
描述: 这是默认的优先级,用于大多数普通的更新任务。React会根据当前的工作负载来决定何时执行这些任务
使用场景: 数据更新、状态变更等常规操作

低优先级(LowPriority)

优先级值: 4
描述: 这个优先级用于那些可以稍后执行的任务,通常是一些不紧急的更新或后台任务。
使用场景: 数据预取、日志记录等不紧急的操作

空闲优先级(IdlePriority)

优先级值: 5
描述: 这是最低的优先级,用于那些可以在浏览器空闲时执行的任务。这些任务不会影响用户交互和页面渲染。
使用场景: 非关键的统计、分析等任务

React的调度器(Scheduler)

React使用一个称为“调度器”(Scheduler)的模块来管理任务的优先级。调度器负责决定何时执行哪些任务,以确保高优先级的任务能够及时得到处理,而低优先级的任务则可以在空闲时执行

优先级的调度机制

React的调度器会根据任务的优先级来决定任务的执行顺序。高优先级的任务会被优先执行,而低优先级的任务则会被推迟到浏览器空闲时执行。React使用浏览器的requestIdleCallback API来实现空闲时执行低优先级任务

时间切片(Time Slicing)

React的并发模式引入了时间切片的概念,即将任务分成多个小片段通过 5ms 的时间分片(默认值)控制每次循环的执行时间,在每个时间片内执行一部分任务。这样可以避免长时间的任务阻塞主线程,确保用户交互的流畅性

  • 使用 MessageChannel(或 setTimeout 作为降级)模拟 requestIdleCallback,在每一帧的空闲时间执行任务
  • 每次执行任务前检查已用时间,超过分片时间则暂停任务,将控制权交还浏览器(避免阻塞渲染)
function workLoophasTimeRemaining {  while currentTask && hasTimeRemaining {    performTaskcurrentTask;  }  if currentTask {    // 时间用尽,通过宏任务(如 MessageChannel)继续调度    scheduleCallback;  }}

任务中断与恢复

React的调度器支持任务的中断与恢复。如果一个高优先级的任务需要执行,React可以中断当前正在执行的低优先级任务,优先处理高优先级任务。待高优先级任务完成后,再恢复低优先级任务的执行

如何使用优先级

在React中,开发者通常不需要直接操作任务优先级,React内部会自动处理任务的调度。

  • 空闲期执行:在浏览器一帧的 空闲时间(Idle Period) 执行任务
  • 帧预算(Frame Budget):默认每帧分配 5ms 给 React,剩余时间留给浏览器渲染
  • 输入响应优化:通过监听 onInput 等事件,主动提升相关任务的优先级

在某些高级场景下,开发者可以通过以下方式影响任务的优先级

useTransition Hook

useTransition 是React提供的一个Hook,用于在并发模式下管理任务的优先级。通过useTransition,开发者可以将某些更新标记为低优先级,从而避免阻塞高优先级的用户交互

useDeferredValue Hook

useDeferredValue 是另一个用于管理优先级的Hook。它允许开发者延迟某个值的更新,从而避免高优先级的任务被阻塞