Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Traverse Elements in DOM tree
(version: 0)
What's the fastest way to find all elements of a certain criteria within a DOM tree?
Comparing performance of:
Manual traversal function vs NodeIterator vs TreeWalker
Created:
3 years ago
by:
Guest
Jump to the latest result
HTML Preparation code:
<div id="traversal-root"> <div> <div> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> <div><div><div><section></section></div></div></div> </div> <div> <div><section><section><div></div></section></section></div> <div><div><div><div></div></div></div></div> <section><div><div><div></div></div></div></section> </div> <section> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> </section> <div> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> </div> </div> <div> <div> <div><div><section><div></div></section></div></div> <div><div><section><div></div></section></div></div> <div><div><div><div></div></div></div></div> </div> <div> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> <div><div><div><section></section></div></div></div> </div> <div> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> </div> <section> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> <div><div><div><div></div></div></div></div> </section> </div> <section> <section> <section><section><section><section></section></section></section></section> <div><div><div><section></section></div></div></div> <div><section><div><div></div></div></section></div> </section> <section> <div><div><div><section></section></div></div></div> <div><div><div><section></section></div></div></div> <section><div><section><section></section></section></div></section> </section> <div> <div><div><div><section></section></div></div></div> <div><section><div><div></div></div></section></div> <section><div><div><div></div></div></div></section> </div> <div> <div><section><div><div></div></div></section></div> <div><div><div><section></section></div></div></div> <section><div><section><div></div></section></div></section> </div> </section> </div>
Script Preparation code:
window.symbol = Symbol('symbol'); window.traversalRoot = document.getElementById('traversal-root'); for (const el of traversalRoot.getElementsByTagName('section')) { Object.defineProperty(el, window.symbol, { value: {} }); } window.isMatch = function isMatch(element) { return element[symbol] !== undefined; } window.traverse = function traverse(element, callback) { if (isMatch(element)) { callback(element); } else if (element instanceof HTMLSlotElement && element.assignedNodes().length) { for (const child of element.assignedElements()) { traverse(child, callback); } } else { for (const child of element.children) { traverse(child, callback); } } };
Tests:
Manual traversal function
const results = []; traverse(traversalRoot, function callback(element) { for (const child of element.children) { traverse(child, callback); } results.push(element); })
NodeIterator
const nodeIterator = document.createNodeIterator( traversalRoot, NodeFilter.SHOW_ELEMENT ); const results = []; let element; while (element = nodeIterator.nextNode()) { if (isMatch(element)) { results.push(element); } }
TreeWalker
const treeWalker = document.createTreeWalker( traversalRoot, NodeFilter.SHOW_ELEMENT ); const results = []; let element; while (element = treeWalker.nextNode()) { if (isMatch(element)) { results.push(element); } }
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (3)
Previous results
Fork
Test case name
Result
Manual traversal function
NodeIterator
TreeWalker
Fastest:
N/A
Slowest:
N/A
Latest run results:
No previous run results
This benchmark does not have any results yet. Be the first one
to run it!
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
**Benchmark Overview** The provided benchmark measures the performance of three different approaches to traverse an HTML document and collect all element nodes: 1. **Manual Traversal Function**: A custom function that recursively traverses the DOM by iterating over each child node. 2. **NodeIterator**: An API that allows traversal of a node's children without loading the entire DOM into memory. 3. **TreeWalker**: Another API for traversing the DOM, similar to NodeIterator. **Benchmark Definitions** Each benchmark definition is contained within two sections: 1. **Individual Test Cases**: A JSON array containing three objects, each representing a test case. * Each object contains: + **Benchmark Definition**: The code that performs the traversal and collects element nodes. + **Test Name**: A human-readable name for the test case. 2. **Latest Benchmark Result**: A JSON array containing the results of the latest benchmark runs. **Approach Comparison** The three approaches have different performance characteristics: * **Manual Traversal Function**: This approach is straightforward but inefficient due to its recursive nature, which can lead to stack overflow errors for deep documents. * **NodeIterator**: This API uses an iterator to traverse the DOM, making it more memory-efficient than the manual function. However, creating a node iterator involves more overhead compared to simply walking through the DOM using `nextElementSibling`. * **TreeWalker**: Similar to NodeIterator, TreeWalker is designed for efficient traversal of complex documents and provides better performance than manual iteration in many cases. **Conclusion** When it comes to traversing an HTML document and collecting element nodes, each approach has its strengths and weaknesses. The choice between Manual Traversal Function, NodeIterator, or TreeWalker depends on the specific use case and performance requirements: * **Manual Traversal Function**: Use when you need more control over the traversal process but are willing to accept potential memory limitations. * **NodeIterator** and **TreeWalker**: These APIs offer better performance for large documents due to their iterator-based approach. However, creating an iterator or tree walker might introduce additional overhead compared to a simple `nextElementSibling` walk. In this specific benchmark, the TreeWalker approach performs the best, followed closely by NodeIterator. The Manual Traversal Function falls behind due to its inherent inefficiencies and potential stack overflow issues.
Related benchmarks:
find vs findIndex (Array prototype methods) with console.log
find vs findIndex (Array prototype methods) - using objects
find vs findIndex (Array prototype methods) 123123
find vs findIndex with accesing the elemnt through index
Switch/case vs indexOf
Comments
Confirm delete:
Do you really want to delete benchmark?