|
JavaScript Loops7 June 2021 As JavaScript interpreters get more sophisticated, their performance behaviours get more complex and more challenging to understand. Let's take the following code which counts to 100 million: console.time('100M test'); for (var i = 0; i < 100000000; i++) { if (i === null) alert(); } console.timeEnd('100M test'); How you run this code make a huge difference.
These tests reveal several important facts when dealing with performant code.
With this out of the way, here's a simple tool that wraps the user-provided code inside a function, runs it five times (to allow the function to 'warm up'), and prints the results to the browser console.
Now that we know the environment in which to run performant code, let's look at the best ways to loop in JavaScript. First let's try a simple "for" loop.
One optimization is to cache the length. This has a noticeable speed up in Chrome, at the expense of a small penalty in Firefox.
ES6 adds the "for-of" loop. It's just a performance disaster in every browser. Avoid this construct for performant code.
Likewise, the technique of looping through non-falsy values without checking length is not advisable.
Not surprisingly, "while" loops are the same as "for" loops. Just more verbose.
The performance of unrolled loops is wild. Horrible initial penalty when cold, then dramatic warmup after one or two executions.
Arrays are not the only thing one loops over. NodeLists are unusual in that they are generators. This changes the performance curves. A regular for loop (with cached length) is much slower on a NodeList than on an array.
The non-falsy value technique which used to be recommended by the Google JS style guide is now slower than a regular loop with cached length.
Since NodeLists are generator, maybe a "for-of" loop would be faster? Absolutely the opposite.
So to summarize, when writing performant JS loops:
This research is accurate as of June 2021. Edge 91 performs identically on all tests as Chrome 91. Sorry, I can't run MSIE on my Mac. Let me know if you have any thoughts. |