替换使用setTimeout
setTimeout是JavaScript中常用的定时器函数,但它存在一些重要的缺陷
- 定时不精确,由于 JavaScript 的单线程特性,
setTimeout不能保证在精确的时间后执行 - 性能会有影响,
setTimeout执行时间不确定,可能会导致主线程卡顿
JavaScript提供了另外两种类似的函数,在某些场景中比setTimeout更加适用
# requestAnimationFrame
requestAnimationFrame函数要求传入一个回调函数,调用后会在下一次重绘之前,调用用户提供的回调函数,该函数主要用于解决动画卡顿的问题。详情见官方文档:window.requestAnimationFrame
function animate() {
requestAnimationFrame(animate)
}
animate()
1
2
3
4
5
2
3
4
5
requestAnimationFrame完美地解决了高优先级视觉任务的调度问题,但如果我们将一个非紧急、耗时较长的后台任务(比如发送日志、数据预处理)放进requestAnimationFrame,就又回到了老问题:它仍然会阻塞关键的渲染路径,导致卡顿。
# requestIdleCallback
requestIdleCallback(callback, options)函数的核心是在浏览器主线程的“空闲时期”执行低优先级的回调函数。该函数同样要求传递回调函数,但它只会在主线程空闲时才会调用不影响性能。为了保证回调函数被执行,可在options参数中传入timeout数值,如果回调在timeout毫秒过后还没有被调用,那么回调任务将放入事件循环中排队,即使这样做有可能对性能产生负面影响。详见官方文档:window.requestIdleCallback
requestIdleCallback(() => {
console.log('Browser is free')
})
1
2
3
2
3
requestIdleCallback函数可将阻塞任务调度到“空闲”时期执行可极大的提高用户体验。同时requestIdleCallback函数返回一个ID值,可以调用cancelIdleCallback函数取消回调执行。
上次更新: 2025/09/05, 8:09:00