// language=HTML
const html = `
<!-- article out start -->
<article>
<!-- article in start -->
<h1>Lorem ipsum</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque, nostrum.</p>
<!-- article in end -->
</article>
<!-- article out end -->
<!-- article out start -->
<article>
<!-- article in start -->
<h1>Lorem ipsum</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque, nostrum.</p>
<!-- article in end -->
</article>
<!-- article out end -->
<!-- article out start -->
<article>
<!-- article in start -->
<h1>Lorem ipsum</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque, nostrum.</p>
<!-- article in end -->
</article>
<!-- article out end -->
`;
const template = document.createElement('template');
template.innerHTML = html;
window.testTemplate = template;
window.testTraverse = function traverse(node, use) {
if (!node) return;
use(node);
traverse(node.firstChild, use);
traverse(node.nextSibling, use);
}
const comments = [];
testTraverse(testTemplate.content.firstChild, node => {
if (node.nodeType === Node.COMMENT_NODE) {
comments.push(node);
}
});
const nodeIterator = document.createNodeIterator(
testTemplate.content,
NodeFilter.SHOW_ALL,
{
acceptNode(node) {
if (node.nodeType === Node.COMMENT_NODE) {
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_REJECT;
}
}
);
const comments = [];
while (nodeIterator.nextNode()) {
comments.push(nodeIterator.currentNode);
}
const nodeIterator = document.createNodeIterator(
testTemplate.content,
NodeFilter.SHOW_COMMENT
);
const comments = [];
while (nodeIterator.nextNode()) {
comments.push(nodeIterator.currentNode);
}
const treeWalker = document.createTreeWalker(
testTemplate.content,
NodeFilter.SHOW_ALL,
{
acceptNode(node) {
if (node.nodeType === Node.COMMENT_NODE) {
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_REJECT;
}
}
);
const comments = [];
while (treeWalker.nextNode()) {
comments.push(treeWalker.currentNode);
}
const treeWalker = document.createTreeWalker(
testTemplate.content,
NodeFilter.SHOW_COMMENT
);
const comments = [];
while (treeWalker.nextNode()) {
comments.push(treeWalker.currentNode);
}
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Traverse function | |
NodeIterator with filter function | |
NodeIterator with filter param | |
TreeWalker with filter function | |
TreeWalker with filter param |
Test name | Executions per second |
---|---|
Traverse function | 256352.4 Ops/sec |
NodeIterator with filter function | 39205.5 Ops/sec |
NodeIterator with filter param | 880580.5 Ops/sec |
TreeWalker with filter function | 108970.4 Ops/sec |
TreeWalker with filter param | 1010300.9 Ops/sec |
Let's dive into the world of JavaScript DOM traversal.
What is being tested?
MeasureThat.net is testing three different methods to traverse the Document Object Model (DOM) in HTML documents:
Options compared
Each test case compares two different approaches:
Traverse function
vs. NodeIterator
NodeIterator
vs. TreeWalker
These comparisons help measure the performance differences between each approach.
Pros and cons of each approach:
Other considerations:
Benchmark results
The latest benchmark results show that:
Traverse function
outperforms NodeIterator
and TreeWalker
for the most recent iOS version.NodeIterator
and TreeWalker
are relatively close in performance, but NodeIterator
is faster on older versions of iOS.These results suggest that, on average, the Traverse function
performs better than NodeIterator
, while NodeIterator
takes a lead over TreeWalker
. However, it's essential to consider individual document structures and edge cases when choosing an approach for your specific use case.