React scheuler profiling

79 阅读1分钟

scheduler模块是React中非常重要的一个模块,负责任务的调度。 为了更好的理解它,我们可以利用它的profiling功能,它以日志的形式记录了任务调度的关键事件点。

profiling的源码地址为SchedulerProfiling.js

日志格式

以log的形式记录scheduler调度事件,记录在变量eventLog中,如下所示:

eventLog:

[
  // 任务开始
  [TaskStartEvent, ms * 1000, task.id, task.priorityLevel]
  // 任务结束
  [TaskCompleteEvent, ms * 1000, task.id]
  // 任务取消
  [TaskCancelEvent, ms * 1000, task.id]
  // 任务错误
  [TaskErrorEvent, ms * 1000, task.id]
  // 任务执行
  [TaskRunEvent, ms * 1000, task.id, runIdCounter]
  [TaskYieldEvent, ms * 1000, task.id, runIdCounter]
  [SchedulerSuspendEvent, ms * 1000, mainThreadIdCounter]
  [SchedulerResumeEvent, ms * 1000, mainThreadIdCounter]
]

一条log记录的基本格式: [event, time, taskId, ...] 其实time如日志记录的时间点。

需要注意的是,在react的实现中,eventLog是以二进制的方式存储的

可视化日志

SchedulerProfiling.js的任务就将这些事件记录到eventLog,关于的eventLog的使用,一个很好的例子在SchedulerProfiling-test.js文件中有一个stopProfilingAndPrintFlamegraph函数, 它读取evnetLog并以可视化的形式展示出来, 如下所示:

!!! Main thread              │██░░░░░░░░██░░░░░░░░░░░░
Task 2 [User-blocking]       │        ░░░░██████
Task 1 [Normal]              │  ████████░░░░░░░░██████

可以清楚的看到任务的执行过程, 上图对应的eventLog如下所示:

TaskStartEvent 100000 1 Normal
TaskRunEvent 100000 1
TaskStartEvent 400000 2 User-blocking
TaskYieldEvent 500000 1
TaskRunEvent 600000 2
TaskCompleteEvent 900000 2
TaskRunEvent 900000 1
TaskCompleteEvent 1200000 1

我使用的react的版本为18.1.0, 目前只看到react在单元测试中使用了该功能,具体的玩法后面再补~