前端 `Scheduler` 任务调度器 应用场景有哪些?
今天看一篇老外的性能优化文章
https://web.dev/optimize-long-tasks/#a-dedicated-scheduler-api
偶然 看到了 Scheduler
MDN 上的介绍https://developer.mozilla.org...
大概意思就是可以 调度用户代码的优先级?
但是 实在想不到 有哪些应用场景, 比如我两个函数
const fnA = ()=>{console.log('aaa')}
const fnB = ()=>{console.log('bbb')}
想要 先执行 fnA
再执行 fnB
fnA()
fnB()
这样不就好了, 还是我对 这个 调度器 理解有误?
恳请 大佬解惑!
回复
1个回答

test
2024-07-12
首先明确一点,对于原本不可控,现在需要控制
的流程,才需要引入 调入机制
- 对于 同步任务,调整代码顺序就能控制,可以直接排除无需讨论
对于将要执行的
异步任务
,可能在某些场景下,你想要后排入的 异步任务 先执行,这种场景下才需要 调度。- 那么就有了第一个问题,如何调度,按照什么规则调度 ?这里就需要引入
优先级
的概念,在发起 异步任务 时,为该任务分配一个 优先级,后续调度器
进行任务调度时,先执行谁,后执行谁,才有依据
- 那么就有了第一个问题,如何调度,按照什么规则调度 ?这里就需要引入
这里我们假设一个需求场景
// main.js
// 先派发一个 低优先级 的耗时异步任务:请求第三方配置信息
scheduler.postTask(() => console.log('低优耗时任务:请求第三方配置信息'), {
priority: 'background',
});
// 执行一段耗时的同步代码阻塞主线程:模拟系统初始化
(() => {
console.time('init')
for(let i = 0; i < 10000000000; i++) {}
console.timeEnd('init')
})()
// 假设此时用户点击了一个按钮,按钮事件触发的 逻辑 需要在 系统初始化完后 优先被响应
document.querySelector('userButton').click()
// ------------------------------------------------------
// event.js
// 在事件注册的位置,我们可以派发 高优先级的 异步任务,来保证 其先于 低优先级任务 被调度执行
document.querySelector('userButton').addEventListener('click', () => {
scheduler.postTask(() => console.log('高优先级任务:用户交互'), {
priority: 'user-blocking',
});
})
调度机制
除了 可指定任务优先级的能力 之外,还具备 取消任务
的能力。同样这里假设一个 页面切换 的场景:
- 有两个页面,加载每个页面会渲染 1000 个组件
- 在对页面进行频繁切换时,就可能会出现性能问题,原因是进入一个页面时,会开启渲染组件的流程,这是一个耗时任务。假设这时切换页面,由于
主线程
还在进行上一个页面的组件渲染,就会出现卡顿,页面无法响应的现象
对于这种场景,我们可以把 每个组件的渲染 拆分开,交由调度器去调度
const tasks = [];
// 渲染组件
components.forEach((component) => {
const abortTaskController = new TaskController();
tasks.push(abortTaskController)
// 每个组件的渲染 交给调度器
scheduler.postTask(() => component.init(), {
priority: 'user-visible',
signal: abortTaskController.signal
});
})
// 当切换页面时, 取消之前已经 派发 但还未执行的任务
tasks.forEach((task) => task.abort())
注意:以上代码均不完整,仅作演示
最后,有兴趣可以了解下 react scheduler
,这是 react 实现的调度器,或许可以帮助你走进 认识调度器 的大门
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容