A quick way to find big elements buried in the DOM

I'm profiling a web page. Browser tools can tell me where we're spending processor time and what kind of objects take up the bulk of the memory. In the page that I'm looking at, DOM nodes account for 80% of memory use. That's unusual. Which parts of the DOM are so big?

Let's find out.

let all = document.querySelectorAll("*"); for (let e of all) delete e.dataset.markupSize /* for idempotency */; for (let e of all) e.dataset.markupSize = e.outerHTML.length

(Yes, we're changing the DOM in the same loop where we're measuring it, but in this case it's safe.)

Calling querySelectorAll returns elements in tree order, so we don't add data-markup-size to an element until we've already finished measuring all of its parents, so the data-markup-size attributes we add never appear in the outerHTML values we measure. If you're not convinced, follow the specs for querySelectorAll > "scope-match a selectors string" > "match a selector against a tree" > "shadow-including tree order" and compare results with let all = document.querySelectorAll("*"); for (let e of all) delete e.dataset.markupSize; for (let e of all) e.myTempField = e.outerHTML.length; for (let e of all) e.dataset.markupSize = e.myTempField)

You might object that

and you'd be right. This is nothing more than a quick heuristic in the same vein as adding * { border: 1px solid red } to highlight areas with too much DOM nesting.

On the other hand, without a snippet to locate heavier parts of the DOM, would you ever have discovered that 2/3 of the markup on this page is a hidden paragraph of lorem ipsum text?

Published 2024-01-22

Next: You can stream text (but not Markdown) without using JS

Previous: What happens when you put random data through a PNG decoder?