0%

javascript-simulate-a-50ms-task

介绍

今天在写前端性能监控的文章时,需要模拟一个长任务,所谓长任务就是指阻塞主线程超过50毫秒的任务。

这种任务当然直接交给AI做了,我给了AI一个提示:帮我模拟一个执行事件超过50毫秒的JavaScript任务。

于是AI给了以下几个代码片段:

使用Busy-Wait来模拟一个长任务

使用Busy-Wait来模拟一个长任务,这个实现没啥毛病,也是我最终采用的方案,就是阻塞主线程直到50毫秒过去:

1
2
3
4
5
6
function simulateLongTask() {
const start = performance.now();
while (performance.now() - start < 50) {
// 模拟一个长任务
}
}

使用setTimeout来模拟一个长任务

下面这个实现使用setTimeout来模拟一个长任务。

1
2
3
4
5
6
7
function simulate50msTask() {
const start = performance.now();
setTimeout(() => {
const end = performance.now();
console.log(`Task took ~${end - start}ms`);
}, 50);
}

但是这个长任务是有问题的,它不会阻塞主线程,因为setTimeout是异步的,所以它不会在50毫秒内阻塞主线程。

这可能是一个常见的误区吧,setTimeout中的延时参数并不意味着主线程会在这个时间内被阻塞,它只是告诉浏览器在指定的时间后执行回调函数。

结论

所以,如果要模拟一个长任务,不能使用setTimeout,最好的办法就是使用循环(while, for)等待的方式,直到耗尽给定的时间。