Minimizing DOM Nodes for Performance

How to win ~200ms with simple HTML refactoring

Joonas Tanner
Expedia Group Technology
4 min readSep 24, 2019

--

You know those things that just make sense, yet you don’t have actual scientific proof to verify them? We at Vrbo™ (part of Expedia Group™) had been looking for an accurate way to prove how the size of the HTML structure/DOM on a page actually affects the performance of our site to our end users. We found a perfect example to measure, and refactored it to shave 200ms from our render time.

What are DOM nodes?

Your web browser parses HTML documents and builds a Document Object Model (DOM) that it can easily understand and manage. In this format, it can be easily understood — and modified — by a scripting language such as JavaScript.

Google recommends the DOM:

  • Have fewer than 1,500 nodes in total
  • Have maximum depth of 32 nodes
  • Have no parent node with more than 60 child nodes

Why do we care?

Imagine you are a web browser. Or React’s virtual DOM. Or a piece of JavaScript that watches the page’s DOM structure for changes (such as to marketing tags).

Imagine you are given an HTML document with thousands of different HTML tags and somehow you need to make sense of it all. It’s a lot of work, right?

In a component-based UI architecture, it is easy to forget that in the end, we are serving HTML documents to our customers’ web browsers. What naturally happens over time, when a team is focusing on delivering new features to the end users, is that the HTML may end up becoming bloated.

This makes things hard for all those poor web browsers to manage. In short — the more HTML content the browser has to parse through and manage, the slower that process will be.

Simple, right? However, this can be surprisingly difficult to prove scientifically. Minor changes to the HTML/DOM structure usually don’t make enough of an impact on performance for us to be able to verify their exact impact.

What did we discover?

Recently in the Web Platform team here at Vrbo, we were analyzing and improving the client-side performance of our pages and components, trying to make the user experience of our website even smoother than it already is.

During the analysis, we noticed that due to a regression caused by refactoring, our Star Rating React component (which displays star icons based on the user rating of a vacation rental property) had started creating each star icon as a separate, inline SVG image. This bloated the HTML/DOM with a lot of unnecessary tags/nodes.

The issue was most visible on our Search Results page, where we display up to 50 properties. Because each property is displayed with its star rating, every additional DOM node in the star rating gets multiplied 50 times.

Chrome dev tools showing how each star icon was a separate, inline SVG element

What did we change?

We refactored the React component, reducing the DOM nodes for each star rating from 25 each down to a single one. We did this by converting the inline SVG icons to CSS background images, utilizing the :before and :after CSS pseudo-elements to display the icons based on a simple CSS class.

As I mentioned, every change gets multiplied 50x on our Search Results Page. This change meant that we reduced the Star Rating DOM nodes from 1,250 down to just 50 on the page — that is a whopping reduction of 1,200 DOM nodes. This might just be enough to help us prove the performance impact!

What was the impact of the change?

We measure the performance of our web site in various ways. One of these is Real User Monitoring. We have a metric called “Primary Action Rendered” that measures how long it takes for the most important feature of the page to be rendered to our end users.

This simple Star Rating component refactoring improved this metric by around 200ms!

This is pretty huge; that means around 0.2 seconds saved for every end user — all from such a simple HTML optimization!

We also saw the Frames Per Second metric improve by 6–20%.

These results were for the extreme example of our Search Results page. Nevertheless, thanks to a component-based architecture, all of our pages can inherit the same performance improvements by simply updating to the latest version of our Star Rating component.

What can you do?

Great! So now we have proof that minimizing DOM nodes/HTML structure really has a positive impact on performance and user experience! What next?

Here are some things that can help to reduce the DOM nodes on your own web site. Your end users will love it!

  • Remember: your page is a document, so it should read like one, even without any styles.
  • Always use semantic HTML. Try designing the minimal HTML content structure before implementing your component and CSS styles.
  • Utilize CSS pseudo elements (like :before and :after) as much as possible.
  • Use React’s <Fragment> whenever possible to avoid adding unnecessary divs/spans to the document (all those divs will add up).
  • Periodically audit your pages and components for DOM bloat accumulated over time.
  • Help out that old, slow web browser by keeping things simple.

Most importantly: Put yourself in the shoes of your customers. Everybody likes a fast-loading web site. ⚡️

--

--