react scheduler

252 阅读2分钟

调度器

  • 宏任务:

    • setTimeout:兼容性好,执行时机不固定,通常在1ms-10ms范围,主流在4ms的样子;
    • MessageChannel:执行时机优先于定时器,官方讲cpu利用率高于rAF,通常晚于rAF执行(时机问题);
    • requestAnimationFrame:帧渲染前js最后的机会,执行时序不太符合分片理念(并非完全意义上的空余时间),16.9版本移除;
  • 任务堆:

    • taskQueue:同步任务小顶堆,按过期时间(当前时间)、id排序
    • timerQueue:延迟任务小顶堆,按过期时间(当前时间 + 延迟时间)、id排序
  • 分片:

    借鉴requestIdleCallback,利用帧与帧之间空闲时间执行

    • 任务间隔:5ms,也就是默认分片间隔
    • 任务暂停:now > deadline
    • 分片计算:根据帧率重计算分片间隔(但目前没有使用)
  • 流水线:

    任务入堆,宏任务等待调度,循环执行并判断是否还有空余时间

    • schedulerCallback:按任务类型入堆,同时执行调度任务
    • requestHostCallback:发送mc消息,等待浏览器执行调度
    • performWorkUntilDeadline:计算deadline,执行调度方法,完成时判断是否继续发送mc消息
    • flushWork:调度方法入口,进行loop
    • workLoop:循环调度,在deadline批量执行任务
  • 优先级:

    不同优先级事件的开始时间/过期时间不同,同优先级事件入堆顺序不同,故高优先级事件最早执行 延迟任务的开始时间不同 同步任务的过期时间不同

    • immediate:立即执行,如渲染
    • userBlock:用户交互类型,如鼠标移动、滚动
    • normal:effect执行等
    • low:未使用
    • idle:未使用
  • API:

    • runWithPriority:插入优先级任务(同步,立即执行,并记录当前优先级等待重置),包括派发用户交互方法、flush当前更新任务队列、添加过渡任务、提交更新方法、低优先级的effect方法等;

    • scheduleCallback:添加调度分片任务(异步),包括flush当前更新任务队列、sync/concurrent更新方法、低优先级的effect方法等;