// 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;
const comments = [];
function traverse(node) {
if (!node) return;
comments.push(node);
traverse(node.firstChild);
traverse(node.nextSibling);
}
traverse(testTemplate.content.firstChild);
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 | 826807.2 Ops/sec |
NodeIterator with filter function | 124906.9 Ops/sec |
NodeIterator with filter param | 1585992.6 Ops/sec |
TreeWalker with filter function | 280290.8 Ops/sec |
TreeWalker with filter param | 1308477.2 Ops/sec |
I'll break down the benchmark and its components for you.
Benchmark Definition
The benchmark tests three different ways to traverse the DOM (Document Object Model) in JavaScript: traverse
function, NodeIterator
, and TreeWalker
. The goal is to compare their performance.
Options Compared
Pros and Cons
Other Considerations
Library/Library-like Features
None of the approaches rely on a specific library, but they do utilize browser APIs:
document.createNodeIterator
and document.createTreeWalker
are part of the DOM API.acceptNode
function in NodeIterator and TreeWalker filter functions is also part of the DOM API.Special JS Features/Syntax
None of the approaches explicitly use special JavaScript features or syntax, but they do rely on:
In summary, this benchmark compares three different ways to traverse the DOM tree in JavaScript: a custom traverse
function, NodeIterator
, and TreeWalker
. Each approach has its pros and cons, and the choice of which one to use depends on the specific requirements of your project.