时间切片本质是将长任务拆为≤20ms的小块穿插执行以保响应性;需用performance.now()动态监控耗时、保存断点、优选rAF/rIC调度,并支持优先级、暂停恢复及监控兜底。

任务队列执行时间切片,本质是把一个可能阻塞主线程的长任务,拆成多个控制在 50ms 以内 的小块,穿插在浏览器每一帧的空闲时段中执行,从而让页面保持响应、不卡顿。
明确单次执行时长上限
浏览器一帧约 16.6ms,但 JS 执行不能占满整帧——需为 layout、paint、用户交互留出余量。实际推荐单次切片执行不超过 10–20ms(保守起见可设为 16ms),超过即主动中断。
- 用
performance.now()记录起始时间,在循环或递归处理中实时判断已耗时 - 避免依赖固定迭代次数(如“每次处理 10 条”),因为每条数据处理耗时不均,易超时
- 中断后需保存当前处理位置(如数组索引、游标或状态对象),供下一轮继续
选择合适的调度时机
不是所有异步机制都适合时间切片:优先使用 requestAnimationFrame(rAF)或 requestIdleCallback(rIC),而非 setTimeout 或 Promise.then。
-
rAF适合与渲染强相关任务(如动态插入 DOM、动画计算),它保证在下一帧绘制前执行,视觉反馈及时 -
rIC更适合纯计算类任务(如数据格式转换、搜索过滤),它会在浏览器空闲时触发,不抢占渲染资源 - 避免嵌套多层
setTimeout(0),它会退化为宏任务排队,延迟不可控且易堆积
构建可恢复的任务队列
把原始任务抽象为队列项,每个切片只消费一部分,未完成项留在队列中等待下一次调度。
- 队列可基于数组 + 索引,也可封装为 Generator 函数,用
next()控制分段执行 - 支持暂停/恢复/取消:例如用户滚动时暂停列表渲染,滚动停止后再继续
- 加入轻量级优先级字段(如
priority: 'high' | 'normal' | 'low'),高优任务可插队执行
监控与兜底保障
时间切片不是万能的,需配合监控和 fallback 机制防止意外。
- 用
PerformanceObserver监听longtask,发现未被切片的长任务及时告警 - 设置最大重试轮数或总超时时间,避免任务无限分片导致整体延迟过高
- 对极简场景(如仅几百条数据),可直接同步执行;不必为切片而切片,增加复杂度却无收益


















