Optimising the DOM
A large and inefficient page structure (Document Object Model, or DOM) can significantly slow down your website and negatively impact Core Web Vitals metrics. Keeping it reasonably sized and highly efficient is crucial for the overall technical performance of your project and will affect interaction response speeds (INP metric).
In this text, you'll discover what I've learned about the DOM from years of consultancy practice. You'll find out why its overall size matters, how to measure it easily, and how to optimise HTML structure for faster rendering.
Size Does Matter
The DOM, a tree structure of components, tends to grow rapidly in the real world of the web. Adding elements and their nesting in HTML is simple, hence the need to consciously restrain it.
A DOM is considered too large if it has many elements or deep nesting. Google recommends a maximum of 1,400 elements, which is rather stringent—especially for larger sites like e-commerce or applications. From our experience, browsers handle 2,500 DOM elements fairly swiftly.
Once the number of DOM elements exceeds this limit, things start to get complicated rather quickly. Naturally, the smaller and more efficient it is, the better.
Why Must the DOM Be Efficient?
It's essential to recognise that HTML is, in the first phase of preparation by the browser, just a string of structured text. Ideally, this is assembled on the server, then downloaded into the browser, which converts it into a dynamic tree structure. This is the "parsing" process.
Diagram of the rendering process. HTML becomes a DOM through parsing. Upon merging with CSS, it proceeds to layout calculation and screen drawing.
That's not the end of it. DOM construction occurs during the initial rendering process. The rendering process has several steps, and DOM inefficiency negatively impacts each.
-
On the Server
The more complex the DOM, the more data and database queries are required. HTML takes longer to assemble, slowing down the TTFB metric. -
Transferring HTML to the Browser
More data means longer network transmission, impacting metrics like FCP or LCP, which measure loading speed. -
Parsing HTML String and DOM Construction
More elements mean the browser takes longer to convert them into a tree structure. -
Applying Styles and Layout Calculation
More elements mean CSS selectors take longer to apply, and layout calculation takes longer. -
Rendering on the Screen
While browsers optimise this phase well, large DOMs can still cause issues, depending on CSS usage. -
During Each Interaction
The DOM is dynamic, reacting to user inputs and JavaScript. A large DOM takes more time during screen updates.
An efficient DOM reduces the strain on the entire rendering process and saves server resources too.
Info: Understanding rendering is key to a fast web. In our workshops, we'll show you how this fascinating mechanism works, step by step.
How to Test DOM Complexity?
There are several ways to assess your situation:
Lighthouse Report
One of the Lighthouse tool's reports indicates the total number of DOM elements on a page, the maximum DOM depth, and the maximum number of nested elements.
You can see the Lighthouse tool output in our test run report details.
DevTools Console in the Browser
Another method is using the DevTools console. Load the page and run the following code snippet.
[...document.querySelectorAll('*')].length;
In Google Chrome, it looks like this:
The image shows the script's result, indicating 932 elements on the page.
Number of DOM Elements in the “Technical” Report
In our monitoring PLUS, we track the number of DOM elements for each measured page. The graph shows how the site evolved over time.
Graph from the Technical report, showing the evolution of DOM element count over time. It also shows how monitoring detects a homepage error where content was not rendered correctly.
DOM Optimisation
Our recommendations may change your paradigm of how you view HTML structure and DOM today. They might even mildly shock you at first. When it comes down to it, the DOM need not be large, even on truly complex pages.
Delete Everything Unnecessary at Load
The most effective strategy is to delete and lazily load everything that doesn't need to be in the code. How do you determine what to delete? Simply ask yourself these questions:
-
Does the component have significant informational value?
Robots often can't handle certain components, like forms and filters. Thus, they don't need to be in the default code in full structure. -
Is it purely a visual element?
Visual elements must be explained textually in the code for machine information value. Examples include dynamic charts and maps. -
How much added value does the component have for the main content?
Websites are often cluttered with various supplementary information. Examples include chats, side contact boxes, often entire sidebars or footers. These often need not be in the default DOM. -
Is it specific to just one particular user?
Deleting such content significantly increases the likelihood of caching. Examples include user profile boxes and carts, recently viewed products. -
Is content duplicated in any component?
Such components unnecessarily inflate the DOM. Technically, duplication was once the only correct option for coders. This no longer applies with modern CSS. Alternatively, duplicated components can be generated and rendered by JavaScript as needed. A typical example is the main navigation, often coded twice—once for mobile and once for desktop.
Example of correct implementation on alza.cz. The user menu appears in the DOM only after clicking on the dropdown. When closed, it is removed again.
Simplify Components Until They Are Visible
Even if a component, or its content, is important for SEO or accessibility, it doesn't mean it must be in full visual quality during the initial render—especially if the component isn't visible in the first viewport.
How many components will the user actually see? Some are hidden behind interactions, like mega menus, while other components become visible upon scrolling. Does every component really need to be in HTML in its final form?
Optimisation through splitting into simple and rich components is especially effective for elements that repeat on a page multiple times. These typically include directory pages or product listings, as you see in the image.
A more illustrative example is the following code snippet, showing how to load a richer component version using the Intersection Observer:
import React from 'react';
import { useInView } from 'react-intersection-observer';
const Offer = ({ images, title }) => {
const { ref, inView, entry } = useInView();
return (
<article className="offer" ref={ref}>
<div className="gallery">
{!inView ? <Image data={images[0]} /> : <ImagesCarousel data={images} />}
<h3>{title}</h3>
</div>
</article>
);
};
Corresponding with important content and the resulting HTML, you'll find that the DOM skeleton can be quite simple. Visual richness can be supplemented on the frontend during the user's visit.
Optimise Long Lists and Tables
Browsers always take longer to render long lists or large tables. Content must be kept to a reasonable length. A listing with 100 products benefits no one.
Content must always be paginated, and if you want to use infinite scrolling, reuse DOM elements via virtual scrolling or remove already invisible items from the DOM and reserve space for them.

Simplify Component Structures
In UI, many components are often created. With today's modern HTML and CSS capabilities, we need fewer and fewer wrapping elements serving solely layout roles.
A typical example of waste is star ratings and unnecessarily inflating the DOM with separate "stars":
// Bad
<StarRating>
<SVGStar />
<SVGStar />
<SVGStar />
<SVGStar />
<SVGStar />
</StarRating>
This can be resolved with a single element, setting its width and a repeating background.
DOM Optimisation: Practical Examples
As speed consultants, we've undertaken numerous successful DOM optimisations.
DOM can be optimised on nearly every project, as it's often not under direct scrutiny. Let's look at two optimisations that significantly helped and had a positive impact on the INP metric.
On Benu.cz, after consulting with SEO experts, we optimised the mega menu, which had nearly 3,000 elements on each page.

We focused the optimisation on reducing nested subcategories. Less important categories load lazily when the user needs them.

What do you see in the image?
- The impact of optimisation visible on specific pages.
- The entire domain shows a change in the INP metric distribution since the optimisation deployment.
Placeholder Simplified Components
Megaubytovanie.sk is a content-rich project. It's a sort of "Czechoslovak Booking". The website is built on the React framework and contains a large number of directory blocks with offers.

We proposed using simplified components, which provide only SEO-important data when the page loads. This state is visually hidden from the user. The "rich variant" activates when the component appears in the viewport.
Impact of DOM optimisation on the INP metric for the page with offer listings.
Beware of CLS
When optimising the DOM, pay attention to layout stability to prevent rendering speed improvements from causing issues with CLS metric.
Always reserve space in the layout for lazily loaded and simplified components using placeholders. Pay special attention to removing components during scrolling.
Scrolling is not considered a user action in the CLS metric, so layout shifts at this time would be heavily penalised.
Tip: Find a specific example of CLS optimisation using placeholders in the mini-case study on CLS optimisation on Datart's homepage.
Conclusion
The DOM is the skeleton; the DOM is everything.
Nowhere else can you achieve so much optimisation at once as you can here. Therefore, give it the attention it deserves—it will undoubtedly pay off.
An efficient DOM enhances content relevance, increases the chance of indexability through TTFB, and speeds up your product. All of this leads to higher conversions.