Critical Rendering Path(CRP)
Tags: webdev, beginners, performance
Published: 2022-05-22 11:45:34

There are a lot of steps that the browser needs to run to show the initial view of any HTML page to the user. These steps together make what is known as Critical Rendering Path.
Remember, the critical rendering path is all about HTML, CSS, and Javascript. Even though we must try to get other resources(eg: images) shown as soon as possible, they are not going to block the initial rendering.
 
**There are 5 steps involved in CRP:**
1. Document Object Model(DOM)
2. CSS object model(CSSOM)
3. Render Tree
4. Layout
5. Paint.

**Document Object Model(DOM)**

Once the HTML of our page is parsed, an object-based representation of this is created which is known as a Document Object Model.
Consider this snippet:

```
<html>
  <head>
  <link rel="stylesheet" href="style.css">
  <title>101 Javascript Critical Rendering Path</title>
  <body>
    <header>
      <h1>The Rendering Path</h1>
      <p>Every step during the rendering of a HTML page, forms the path.</p>
    </header>
    <main>
         <h1>You need a dom tree</h1>
         <p>Have you ever come across the concepts behind a DOM Tree?</p>
    </main>
    <footer>
         <small>Thank you for reading!</small>
    </footer>
  </body> 
  </head>
</html>
```

This is what a DOM for the above snippet would look like:


![HTML snippet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eivk49mz5t5dw01pjflg.png)

The browser sends a request for the HTML and starts parsing it. The parser sends requests for any CSS links or Javascript, after that it also sends requests for all the other assets found in the rest of the page. When the HTML is wholly parsed, the browser now has all the content, but the browser needs to know the related CSS to show the HTML elements. Now the browser waits for the CSSOM, which will tell the browser how the elements should look when rendered.

**CSS Object Model(CSSOM):**

Just like a DOM is created so that the browser understands it, a CSSOM is created so that the browser understands it and the CSS rules are applied effectively. 

Consider the CSS for the above HTML:
```
header{
   background-color: white;
   color: black;
}
p{
   font-weight:400;
}
h1{
   font-size:72px;
}
small{
   text-align:left
}
```
The CSSOM would look like:

![CSS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jg6wki49a2i5yjam15oq.png)

CSS is a critical resource as it is **render-blocking** (the rendering is stalled until all the CSS resources are loaded). It is render-blocking because showing the HTML without the CSS will not serve a good user experience.

**Render Tree:**
This is the step when the DOM and CSSOM are merged, and together they can render the page.
This render tree has all the information about the content which has to be shown to the user as well as its respective styles(if available).

**Layout:**
This stage is where the browser calculates the positions and dimensions of each visible element on the page.
Whenever the render tree is updated or the size of the viewport changes, this step has to run all over again.

**Painting:**
In this step the layout created is painted by the browser. This step can take time based on the paint styles. 

[Check here to know more](https://www.html5rocks.com/en/tutorials/speed/css-paint-times/)

**Dealing with Javascript:**
Since javascript can manipulate both DOM and CSSOM, the browser should wait for the DOM to be fully constructed and wait for the CSS files to be loaded and parsed completely.

Whenever the browser finds any javascript file, it stalls the HTML parsing and waits for the script to be executed to resume HTML parsing again. Therefore if there are any references of the DOM inside of the script, the script should run after the DOM construction. To deal with this, previously it was recommended to always have the script at the bottom of your body tag.

This approach has its own downsides: the browser cannot start downloading the scripts until the entire HTML is parsed. For larger websites with large scripts, being able to fetch the script as soon as possible is very crucial for performance. 

To tackle this, the modern approach is to use async or defer for the script tags
**async:** the script will be fetched in parallel to parsing and **executed as soon as it is available.**
**defer:** the script will be fetched in parallel to parsing and **executed once the entire document is loaded.**

Both the attributes allow the elimination of **parser-blocking** JavaScript where the browser would have to load and evaluate scripts before continuing to parse.

**Conclusion:**
Now that we know what the critical rendering path is, we can try to analyze the code. Every line, every resource and every file included in the project adds to the critical rendering path. Performance is crucial in any web application. As it grows in complexity and size, every millisecond makes a difference. Nevertheless, remember that premature optimization can be catastrophic. Always make sure every optimization is worth the time and it brings a change.

Happy Coding!