The Business 💰 Value of Speed 🏎 - A How-To Guide - Part 1: The Critical Rendering Path
Tags: webperf, css, webdev, javascript
Published: 2020-07-15 12:18:18

I recently wrote a blog post about "[Why you should care about Web Performance](https://marcradziwill.com/blog/why-you-should-care-about-web-performance/)". It contains a topic collection of how you could convince your client to focus on performance.

**But nothing convinces people more than numbers.** Real business numbers like the conversion rate, the bounce rate and custom business metrics/rates.

I decided to write a simple guide on how you can measure essential site metrics and map them to your business metrics. But before we dive into that, we take a short course into the critical rendering path.

I publish one post of the series a week, so [stay tuned](https://marcradziwill.com/newsletter/?r=511370) for the next three weeks.
You get all three posts on my blog and if you **subscribe to my free newsletter** you are the first to know when they are online.

- Week 1: [Critical Rendering Path](/business-value-of-speed-part-one-critical-rendering-path)
- Week 2: [Measure Key Metrics and map them to Business Metrics](/business-value-of-speed-part-two-metrics-and-mapping-of-business-values)
- Week 3: [Optimizing for your Business value](https://marcradziwill.com/blog/business-value-of-speed-part-three-optimizations/)
---

If you like this article, smile for a moment, please share it, follow me and [subscribe to my newsletter](https://marcradziwill.com/newsletter/?r=511370).

---

## Tldr;

This post is the first of the series about how to get the business value of site speed. In this part, I write about the Critical Rendering Path (CRP) and why it is essential to understand before we can dive deeper.

## Table of Contents

1. [Introduction](#into)
2. [Critical Rendering Path](#crp)

   - [What is the Critical Rendering Path and why is it critical?](#what)
   - [What is included in the Critical Rendering Path?](#included)
   - [Building the DOM (Document Object Model) in action](#dom)
     1. [Convert bytes to characters](#byte2cardom)
     2. [Identify tokens ](#tokensdom)
     3. [Convert tokens to nodes](#convdom)
     4. [Build DOM Tree](#domtree)
   - [Building the CSSOM (CSS Object Model) in action](#cssom)
     1. [Convert bytes to characters](#byte2carcssom)
     2. [Identify tokens ](#tokenscssom)
     3. [Convert tokens to nodes](#convcssom)
     4. [Build CSSOM Tree](#cssomtree)
   - [Layout](#layout)
   - [Paint](#paint)
   - [JavaScript and the CRP](#js)

3. [Critical Rendering Path and it's correlation to the user interaction](#us)
4. [Conclusion](#conclution)
5. [Next steps](#next)

## Introduction <div id="intro"></div>

Everybody talks about it: `Faster == Better`. But what does this mean for your project? What is the Break-Even-Point for your performance, and where is it worth to invest in improvements? It would be too good to be true, but there is no unique solution for every business.

As businesses are not equal, the mapping of speed to business metrics is not similar every time. The good thing is, it is easy to measure your critical indicators for your business as long with the correlating performance metrics. At least in the web performance part, there is a topic that all websites have in common: The Critical Rendering Path.

## Critical Rendering Path <div id="crp"></div>

Before we can go on, we need to take a look at the Critical Rendering Path, and the correlation to the user interaction with the site.

### What is the Critical Rendering Path and why is it critical? <div id="what"></div>

The CRP is a sequence of steps the browser has to complete **before** the user can see anything on the page and interact with it. The critical part is the "before". So no user can interact with your site if the sequence of the CRP is not complete. Therefore this sequence is **critical**. The steps the browser has to go through are valid for every device and any network connection. The browser must load, understand and convert all parts of your website.

### What is included in the Critical Rendering Path? <div id="included"></div>

The CRP includes the following essential parts:

- Building the DOM
- Building the CSSOM
- Building the Render Tree
- Layout the website
- Paint the website
- JavaScript (effects multiple points of CRP)

After the browser loads the HTML, it builds the DOM (Document Object Model), then it fetches the CSS and builds the CSSOM (CSS Object Model) and combine those two into the Render Tree. After that, the browser can figure out where everything goes on the website (Layout), and finally, it can paint the website (Paint). JavaScript can have a massive impact on CRP. Read below how it is involved in building the CRP.

It often feels a little bit like magic how the browser converts our requested website into a picture on the screen. As we dive into the CRP sequence, we cover the performance-related topics. If you are curious about how a website request works in detail, I recommend you to check out this [github repo](https://github.com/alex/what-happens-when).

### Building the DOM (Document Object Model) in action <div id="dom"></div>

When you request a URL, the browser sends a request to the server and receives a response which is the HTML. For the sake of simplicity, I use the HTML example below in this guide. The DOM (Document Object Model) Tree is an Object representation of the fully parsed HTML page. The browser has to process four steps to get the object model:

![Building the Document Object Model (DOM)](https://marcradziwill.com/static/d590ae37397896b7215752aed9df1280/13cec/dom.jpg 'Building the Document Object Model (DOM)]')

#### 1. Convert bytes to characters <div id="byte2cardom"></div>

The browser requests the HTML and converts it from bytes to characters. In this case it is based on the `UTF-8` encoding. So from:

```bash
3c 68 74 6d 6c 3e 0a 09 3c 68 65 61 64 3e 0a 09 09 3c 74 69 74 6c 65 3e 54 68 65 20 43 72 69 74 69 63 61 6c 20 52 65 6e 64 65 72 69 6e 67 20 50 61 74 68 3c 2f 74 69 74 6c 65 3e 0a 09 09 3c 6c 69 6e 6b 20 72 65 6c 3d 22 73 74 79 6c 65 73 68 65 65 74 22 20 68 72 65 66 3d 22 73 74 79 6c 65 2e 63 73 73 22 3e 0a 09 3c 2f 68 65 61 64 3e 0a 09 3c 62 6f 64 79 3e 0a 09 09 3c 68 65 61 64 65 72 3e 0a 09 09 09 09 3c 68 31 3e 54 68 65 20 43 72 69 74 69 63 61 6c 20 52 65 6e 64 65 72 69 6e 67 20 50 61 74 68 3c 2f 68 31 3e 0a 09 09 3c 2f 68 65 61 64 65 72 3e 0a 09 09 3c 6d 61 69 6e 3e 0a 09 09 09 09 3c 68 32 3e 48 65 61 64 6c 69 6e 65 3c 2f 68 32 3e 0a 09 09 09 09 3c 70 3e 41 6e 20 61 77 65 73 6f 6d 65 20 70 61 72 61 67 72 61 70 68 20 74 61 67 2e 3c 2f 70 3e 0a 09 09 3c 2f 6d 61 69 6e 3e 0a 09 09 3c 66 6f 6f 74 65 72 3e 0a 09 09 09 09 3c 73 6d 61 6c 6c 3e 43 6f 70 79 72 69 67 68 74 20 4d 61 72 63 20 32 30 32 30 3c 2f 73 6d 61 6c 6c 3e 0a 09 09 3c 2f 66 6f 6f 74 65 72 3e 0a 09 3c 2f 62 6f 64 79 3e 0a 3c 2f 68 74 6d 6c 3e
```

We get our readable HTML.

```html
<html><head><meta charset="UTF-8" /><title>The Critical Rendering Path</title><link rel="stylesheet" href="style.css"></head><body><h1>The Critical Rendering Path</h1></h2><p>An awesome paragraph tag.</p></body></html>
```

#### 2. Identify tokens <div id="tokensdom"></div>

The browser converts strings of characters into tokens. For example, `<html>`, `<body>` and other strings within angle brackets are converted to tokens. The ruleset for the token generation is specified in [the W3C HTML5 standard](https://www.w3.org/TR/html5/). In our case we find `html`, `head`, `meta`, `title`, `link`, `body`, `h1`, `h2` and `p` and the browser creates tokens for them.

![Tokens of the DOM](https://marcradziwill.com/static/f5ef795f70805065f153c80ccdb43780/8cc63/tokens.jpg 'Tokens of the DOM')

### 3. Convert tokens to nodes <div id="convdom"></div>

From the tokes generated out of the HTML, the browser can create nodes. Each node represents a tag of the DOM, its properties and rules. For our HTML we get the same nodes as we have tokens: `html`, `head`, `meta`, `title`, `link`, `body`, `h1`, `h2` and `p`.

![Nodes of the DOM](https://marcradziwill.com/static/51baf92eef8de55773064a76937a8904/8cc63/nodes.jpg 'Nodes of the DOM')

#### 4. Build DOM Tree <div id="domtree"></div>

The last step is the combination of all identified nodes. As the HTML markup defines relationships between tags, all nodes are linked in a tree structure the Document Object Model Tree (DOM Tree).

![DOM Construction](https://marcradziwill.com/static/bd78b67345ac8b12ff420878172f668b/bdf89/domtree.jpg 'DOM Construction]')

### Building the CSSOM (CSS Object Model) in action

The Document Object Model contains the contents of our site. With the DOM the browser knows what it needs to display on the website. But it doesn't know where and how. For any styling, it requires the CSSOM. The browser has to repeat the steps it took to create the Document Object Model, but this time for CSS instead of HTML. Something to note here, which is essential later is that **CSS is render-blocking** because the browser must parse ALL given styles before he can display elements.

#### 1. Convert bytes to characters <div id="byte2carcssom"></div>

The browser parses the `link`-tag and requests the CSS and converts it from bytes to characters. In our case from:

```bash
62 6f 64 79 20 7b 20 66 6f 6e 74 2d 73 69 7a 65 3a 20 31 36 70 78 20 7d 20 70 20 7b 20 66 6f 6e 74 2d 77 65 69 67 68 74 3a 20 62 6f 6c 64 20 7d 20 68 31 20 7b 20 63 6f 6c 6f 72 3a 20 72 65 64 20 7d 20 68 32 20 7b 20 64 69 73 70 6c 61 79 3a 20 6e 6f 6e 65 20 7d
```

To readably characters.

```css
body {
  font-size: 16px;
}
p {
  font-weight: bold;
}
h1 {
  color: red;
}
h2 {
  display: none;
}
```

#### 2. Identify tokens <div id="tokenscssom"></div>

As CSS has its own set of rules, the browser doesn't identify tokens between the angle brackets. You find a detailed instruction on how the browser creates CSS tokens in the CSS specification.

#### 3. Convert tokens to nodes <div id="convcssom"></div>

The next part of the CSSOM is the node creation from the previously created tokens. These nodes contain the selector; for instance, the `body` and the properties or CSS rules the browser applies later.

#### 4. Build CSSOM Tree <div id="cssomtree"></div>

The last step is the creation of the CSSOM is the CSSOM tree. Like the DOM, it is a tree representation of all related nodes. As the nodes inherit the styles from the parent nodes, the browser can do this easily with a tree structure. The inheritance is why CSS is called Cascading Style Sheets.

![DOM Construction](https://marcradziwill.com/static/5b40f04b4db5c0d5bb9061e75bcf1485/fc9e0/cssomtree.jpg 'DOM Construction]')

### Building the Render Tree <div id="byte2carcssom"></div>

The DOM contains all the content of the website, and the CSSOM includes all the styles of a website. The render tree is the combination of the DOM and the CSSOM. The browser uses the render tree to compute the layout of the page, and it is involved in the painting process of the browser. **A render tree contains only visible elements**.

The creation of the render tree starts at the root of the DOM and traverse it down to the last element in the tree. The browser ignores some of the nodes, as they are not visible on the page. These elements are: `script`, `meta`, `link`, and so on. Additionally, some tags have properties that hide them with CSS, and the browser ignores them as well. See the figure below how the browser creates the render tree for our example.

![DOM Construction](https://marcradziwill.com/static/a3f0329315f3433697d017ce1498582f/a90fb/rendertree.jpg 'DOM Construction]')

### Layout <div id="layout"></div>

The Layout step in the process is how the browser calculates the exact position of all elements in the given viewport. To have a look at a simple example, I changed the HTML from above. You see, it has some layout CSS properties now. The body of our page has two nested elements, and each of them has a `width` of 50%. Note that I added the meta tag `<meta name="viewport" content="width=device-width">` as well. This meta tag tells the browser that the layout viewport should be equal to the device width.

```html
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>The Critical Rendering Path</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <h1>The Critical Rendering Path</h1>
    <div style="width: 50%">
      <div style="width: 50%">An awesome paragraph tag.</div>
    </div>
  </body>
</html>
```

The output of the HTML is a page with a headline and two nested divs. The first one has 50% width of the viewport and the second nested one has 50% of its parent width, so 25% of the viewport.

![Layout of the HTML example page](https://marcradziwill.com/static/d24748f68a81a72012b70e4f02ea16f4/4abeb/layout.jpg 'Layout of the HTML example page]')

### Paint <div id="paint"></div>

Now we are ready to paint pixels. Our content is in the DOM, the styles are in the CSSOM, and the render tree combines this information. The Layout step calculated all the positions and proportions of our elements. The browser is ready to paint pixels. Painting might take some time as it depends on your render tree and the rendering device.

### JavaScript and the CRP <div id="js"></div>

JavaScript has a significant impact on CRP. Let's check out the following example. What you see is a `script` tag, that changes the DOM and the CSSOM. With `headline.textContent = 'The dynamic Critical Rendering Path';` JavaScript changes the content of the `h1`-tag, and at the same time, it changes the DOM structure. In the next line, JS changes the style `display` property to `inline` and therefore changes the CSSOM.

```html
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>The Critical Rendering Path</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <h1>The Critical Rendering Path</h1>
    <div style="width: 50%">
      <div style="width: 50%">An awesome paragraph tag.</div>
    </div>
  </body>
  <script>
    var headline = document.getElementsByTagName('h1')[0];
    headline.textContent = 'The dynamic Critical Rendering Path';
    headline.style.display = 'inline';

    var thatRocks = document.createElement('div');
    thatRocks.textContent = 'that rocks';
    thatRocks.style.color = 'red';
    document.body.appendChild(thatRocks);
  </script>
</html>
```

As you can see, JavaScript is mighty in changing the resulting render tree. But with that power comes some problems. Our script is added right before the `body` end tag. This is for the reason that the HTML parser works incrementally and JavaScript is executed right away. When the HTML parser finds a script tag, it pauses the DOM construction and waits for the execution of JavaScript. **`script`-tags are blocking the DOM construction**.

It gets even worse if the browser hasn't finished downloading the CSS and hasn't created the CSSOM yet. In this case, the browser delays the script execution and the DOM construction until it has finished downloading CSS and creating the CSSOM. **So by default JavaScript execution is parser blocking**. Fortunately, there are some ways to get around this. We check them out in part 3 of my series.

{% link https://dev.to/marcradziwill/mastering-javascript-high-performance-1n76 %}

## 3. Critical Rendering Path and its correlation to the user interaction <div id="ux"></div>

For the user, one of the most important metrics is that the website is usable. Which means the user can interact with the page or at least see the main content. A user loses focus after 1 second (High Performance Browser Networking - Ilya Grigorik).

- 0–100 ms — Instant
- 100–300 ms — Small perceptible delay;
- 300–1000 ms — Loss of focus, noticeable delay;
- 1 s+ — Likely mental context switch;
- 10s+ — Task is abandoned, User leaves;

For our users, this means we need to deliver the website in under 1 second not to lose them. **Fortunately not**. We don't need to deliver the full page in under 1 second. **But we dive more into that topic in part three**. The most important part of this paragraph is that the time we deliver information to our users is significant and should be under 1 second for the content above-the-fold.

## 4. Conclusion <div id="conclution"></div>

Of course, the Critical Rendering Path is not the only part of web performance that has an impact on your business value. Sometimes there isn't even a metric or theory defined for your case.

But the Critical Rendering Path has a significant impact on your business value and the time until the user can interact with the site is essential and should aim to be under 1 second.

In part two, we take a look at the essential metrics of the CRP as well as we define custom metrics for some use business cases that can not use the standard one.

I publish part two next week, so [stay tuned](https://marcradziwill.com/newsletter/?r=511370).

## 5. What's next? <div id="next"></div>

You find all the resources for this article on [GitHub](https://github.com/marcradziwill/critical-rendering-path-tutorial). I use this repo as well for part two and three. Feel free to check it out, try some stuff or fork it.

Now you have an understanding of the Critical Rendering Path and the way a browser processes HTML, CSS and JavaScript.

If you like this article, smile for a moment, share it, follow me, [check out my RSS feed](https://marcradziwill.com/blog/rss.xml) and [subscribe to my newsletter](https://marcradziwill.com/newsletter/?r=511370).

Cheers Marc

### Further Reading

- [Critical Rendering Path](https://developers.google.com/web/fundamentals/performance/critical-rendering-path)
- [Understanding the Critical Rendering Path](https://bitsofco.de/understanding-the-critical-rendering-path/)
- [Critical rendering path](https://developer.mozilla.org/en-US/docs/Web/Performance/Critical_rendering_path)
- [Understanding the critical rendering path, rendering pages in 1 second](https://medium.com/@luisvieira_gmr/understanding-the-critical-rendering-path-rendering-pages-in-1-second-735c6e45b47a)