I'm working on a JS library that can potentially perform long computations, freezing the main thread. I know about Web Workers and they will be used as well, but I would like to ensure that the code can also be executed on the main thread without blocking it.
I've tried the following solution to break long computations up into smaller pieces:
const performLongComputations = () => {
let sum = 0;
for (let i = 0; i < 10_0000; ++i) {
sum += Math.random();
}
};
const synchronousExecution = () => {
let totalTime = 0;
for (let i = 0; i < 1_000; ++i) {
const startTime = performance.now();
performLongComputations();
totalTime += performance.now() - startTime;
}
return totalTime;
};
console.log(`Synchronous execution took ${synchronousExecution()} ms`);
const asynchronousExecution = () => new Promise(resolve => {
let totalTime = 0;
let currentIteration = 0;
const start = () => {
const startTime = performance.now();
performLongComputations();
totalTime += performance.now() - startTime;
if (currentIteration++ < 1_000) {
setTimeout(start, 0);
} else {
resolve(totalTime);
}
};
start();
});
asynchronousExecution().then(time => console.log(`Asynchronous execution took ${time} ms`));
In Chrome, the output is as follows:
Synchronous execution took 837.0999999996275 ms
Asynchronous execution took 2853.699999993667 ms
In Firefox:
Synchronous execution took 9674 ms
Asynchronous execution took 9203 ms
Tested on Linux, Chrome 92.0.4515.107, Firefox 90.0.
There are two things that surprise me: