Appearance
setTimeout 排期与可能的问题
本节目标:理解“setTimeout 排期与可能的问题”的核心思路,并能把它用于实际开发或面试表达。
- 宏任务:setTimeout(fn, delay) 注册的是一个宏任务(Task),放在 “定时器” 阶段执行。
- 4 ms 最小间隔:现代浏览器会把所有小于 4 ms 的 delay 都 clamp 到 4 ms;如果当前页面在后台,很多浏览器会进一步 throttle 到 1000 ms 以上。
- 与重绘不同步:虽然 HTML 规范保证“定时器阶段”发生在绘制前,但不会与每帧精确对齐;如果你的回调需跟动画/UI 同步,就会产生“卡帧”或“抖动”。
- 漂移 (drift):如果回调内部执行时间较长,下次定时器的实际触发会被推迟;不断累加就会导致节奏变慢。
- 后台节流:在不可视标签页或最小化窗口时,浏览器通常会大幅降低定时器的调用频率,甚至暂停调用,导致数据和 UI 更新严重滞后。
可能的问题
- 更新抖动:回调与浏览器每 16.7 ms 一次的重绘不同步,视觉上不连贯。
- 累积延迟:长业务逻辑占用时间会让后续定时器回调不断后移,无法保持稳定频率。
- 不可控的抑制:在后台或能耗模式下,定时器可能被完全暂停,实时性丢失。
小结
- 若追求与浏览器重绘 精确对齐,且需要可控频率,推荐用 useRafFn+节流逻辑。
- 若只是做低频次的非动画更新(比如几百毫秒一次),setTimeout 也能胜任,但要注意浏览器 clamp/drift/后台节流带来的不稳定性。
