I'd like to flatten a DOM tree into an Array
.
The result should include the root as the first entry.
Plain JS solution is preferred.
What's the fastest way to achieve that?
HTML structure example:
<div class="tested-root">
<span></span>
<span></span>
<div>
<span></span>
<span></span>
</div>
<div>
<span></span>
<span></span>
</div>
</div>
The output expected to be:
[div.tested-root, span, span, div, span, span, div, span, span]
or alike (this one is DFS, but doesn't really matter for sake of this question).
From the three methods below which is the fastest:
querySelectorAll
NodeIterator
TreeWalker
I've came to try another few just recently. Below the results from slowest to fastest, while specifying how the one slower than the fastest.
Chrome based results. Safari shows roughly the same numbers. Firefox has issues with that perf app and was not verified.
const list = Array.from(root.querySelectorAll('*'));
list.unshift(root);
const list = [root, ...root.querySelectorAll('*')];
const list = [];
const ni = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT);
let next;
while (next = ni.nextNode()) {
list.push(next);
}
const list = [root];
const tw = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
let next;
while (next = tw.nextNode()) {
list.push(next);
}
const list = [root];
if (root.childElementCount) {
const tw = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
let next;
while (next = tw.nextNode()) {
list.push(next);
}
}
...
) operator way is faster than unshift
methodTreeWalker
being the fastest by farBench tests can be found here.