I found out that running async-await can be much slower in some scenarios.
<html>
<script>
function makeAPromise() {
return Promise.resolve(Math.random());
}
function usingPromises() {
const before = window.performance.now();
return makeAPromise().then((num) => {
const after = window.performance.now();
console.log('Total (promises): ', after-before, 'ms');
return num;
})
}
async function usingAwait() {
const before = window.performance.now();
const num = await makeAPromise();
const after = window.performance.now();
console.log('Total (await): ', after-before, 'ms');
return num;
}
function runBoth() {
usingAwait();
usingPromises();
}
runBoth();
</script>
<button onclick="usingPromises()">usingPromises</button>
<button onclick="usingAwait()">usingAwait</button>
<button onclick="runBoth()">both</button>
</html>
IMO, the console.log in usingPromises
should print similar results to the one in usingAwait
.
But in reality, I get:
Total (promises): 0.25 ms
Total (await): 2.065 ms
Also, after the page load, if I click on 'usingPromises' or 'usingAwait' button I get similar results for each of them. (both are fast when running alone)
Total (promises): 0.060000000026775524 ms
Total (await): 0.08999999999650754 ms
But if I click on the 'both' button, the 'await' version is ~3-4 times slower than the promises version.
I have a real application running lots of promises / async-await function on initialisations, and I found out that replacing some of the async-await functions to their "equal" promises version can shave significant loading time (~200ms).
Can someone explain why is that? Isn't async-await also using the same job queue as promises (micro task)? Are there best practices to when should promises should be used instead of async-await?
Thanks
Test 3 - Promise vs Async/Await When running this on JSBench.Me, the case using promises rather than async/await is shown to be a further 26% slower on Chrome 87 than the async/await case.
Yes, you read that right. The V8 team made improvements that make async/await functions run faster than traditional promises in the JavaScript engine.
await is always for a single Promise . Promise creation starts the execution of asynchronous functionality. await only blocks the code execution within the async function. It only makes sure that the next line is executed when the promise resolves.
The await operator is used to wait for a Promise . It can only be used inside an async function within regular JavaScript code; however it can be used on its own with JavaScript modules.
Your first result, when running with the button Both
, is misleading. The promise resolutions are sequenced in the microtask event queue: so one gets to print with console.log
before the other, but it is that console.log
that brings additional delay to the second, because it happens between the creation of the second promise and the treatment of its resolution.
It would already be an improvement if you would define runBoth
as:
Promise.resolve().then(usingAwait).then(usingPromises)
Now both promises will be created in microtasks, and the first one will be resolved and dealt with before the second promise is created. That will lead to a more fair comparison where console.log
is not measured in any of the timings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With