Skip to the tool
OnPageKit

DOM Size Checker

Count elements, depth and inline bytes in pasted page source.

rendered source, not a URL

Nothing leaves this tab, which is also why the tool cannot fetch a page for you. On a site built by a framework, take the source after hydration from your browser inspector rather than the first response: the count that matters is the tree the browser ends up with.

An icon set drawn inline can add hundreds of paths that no stylesheet ever selects. Folding them away shows what the rest of the page costs; leave it off to see the figure Lighthouse itself would report.

Elements
0
Max depth
0
Max children
0
Document
0 B
  • No elements found. This tool reads markup, so give it the rendered source of a page rather than its address: open the page, view source, and paste what a crawler would receive.

Everything runs in your browser. Nothing you type is sent to a server.

Found a bug in this tool? Report it.

Share this tool

What this DOM size checker measures

Paste the source of a page into this DOM size checker and it counts what a browser has to construct before anything appears: how many elements there are, how deep the deepest branch runs, which parent carries the most direct children, and how the bytes divide between markup, readable text, inline script and inline CSS. Every figure is calculated in the tab you have open.

The three headline numbers line up with the ones Lighthouse reports, because a measurement is only worth having if you can compare it against the threshold that made you look.

Why a big tree is expensive

The tree is not just memory. Every element is a candidate for every CSS rule the page defines, and the browser has to decide, for each of them, which declarations apply. Add a class to the body and the engine walks the whole document again. That work happens on the main thread, and on the main thread it competes with the tap the visitor just made.

Then there is layout. Change the height of one element near the top and everything below is repositioned. On a page of a few hundred elements this is imperceptible; on a page of several thousand it is the difference between a list that scrolls and one that stutters. And on a mid-priced phone, which is the device most of your visitors are actually holding, the gap between those two states is much narrower than it is on the laptop where the page was built.

Depth costs more than width

Two pages of the same size are not the same page. Width — many siblings under one parent — is usually a list, and a list can be paginated or virtualised. Depth is structural, and it is what selector matching pays for: a rule like .card .body p is evaluated from the matched element upwards through its ancestors, so a leaf sitting forty levels down is expensive to style and expensive to reflow.

Depth also tends to be accidental. Nobody designs a forty-level branch. It accumulates: a grid system wraps everything in a row and a column, a component library wraps that in a provider, a layout wrapper wraps the lot again, and each addition is individually defensible. The tool prints the deepest path from root to leaf for exactly this reason — read it once and you can usually see which three wrappers do nothing.

Div soup, and the honest version of the complaint

The report counts div and span against elements that carry meaning: header, nav, main, section, article, ul, li, table, headings, links, buttons. When the generic ones win by a wide margin, the markup has been written for CSS hooks rather than for structure.

This is not a claim that div is bad. Layouts need boxes, and a flex container is a legitimate box. The point is narrower: a <div class="header"> and a <header> are the same weight in bytes, the same weight in the tree, and only one of them tells a screen reader that it has found the banner. When the two counts are close to even, nothing needs doing. When there are eight generic containers for every element that means something, the page is describing its stylesheet instead of its content.

Inline script and CSS are paid for on every view

The byte breakdown separates inline <script> and <style> from the rest, because those bytes behave differently from the rest of the document. An external file is fetched once and served from cache on every later page. An inline block travels with the HTML, every time, uncompressed by any cache, and it cannot be deferred.

Some inlining is deliberate and correct — critical CSS above the fold, a small bootstrapping script. It stops being correct when a plugin appends its own copy on every page. If the inline share of your document is above half, that is where to look first, and it is usually a faster win than removing elements.

When the structure is what you are auditing rather than the size, the heading structure checker reads the same source for outline problems, and the deprecated HTML tags checker finds the elements that survived from an older template — often the same ones inflating the count here.

Frequently asked questions

How many DOM elements is too many?

Lighthouse begins warning around 800 elements and fails the audit at 1,500, with separate ceilings of 32 levels of depth and 60 direct children under one parent. Treat those as thresholds for investigation rather than physics: a 2,000-element table that nobody scrolls costs less than a 900-element page whose JavaScript rewrites it on every keystroke.

Does a big DOM affect ranking directly?

Not by itself. It reaches ranking through Interaction to Next Paint and Cumulative Layout Shift, which are part of the page experience signals, and through crawl efficiency on very large templates. The direct cost is felt by the visitor first — on a mid-range Android, style recalculation over a huge tree is what makes a tap feel late.

Should I paste the HTML the server sent or what the browser ended up with?

What the browser ended up with, in most cases. A React or Vue app ships a small shell and builds the rest at runtime, so view-source shows almost nothing while the real tree is several times larger. Copy the outer HTML of the document element from your inspector after the page has settled. Server-rendered output is the right input only when you want to know what a crawler sees before any script runs.

Why does the tool count elements rather than nodes?

The Lighthouse audit counts elements, and a number is only comparable against a threshold that measured the same thing. Text and comment nodes exist in the real DOM but are not what the audit reports, so they show up here in the byte breakdown instead, where they are actually useful.

What counts as an excessive DOM size on a listing page?

A product grid of 60 cards at 20 elements each is 1,200 elements before the header and footer, which is already past the warning line. The fix is rarely to redesign the card: it is to paginate, to virtualise the list, or to cut the per-card markup down. Halving a card from 20 elements to 10 halves the whole page.

Related tools

Updated