Understanding the critical rendering path

Lecture



The browser has many steps to go through before the HTML response from the server is converted to pixels on the screen. The sequence of these steps required to first render the page is called the Critical Rendering Path.


Knowing about CRP (Critical Rendering Path) is incredibly helpful in understanding how to improve website performance.

There are 6 stages of CRP:

  • building a DOM tree,
  • building a CSSOM tree,
  • running JavaScript,
  • creating a Render tree,
  • generation of layouts,
  • rendering.
    Understanding the critical rendering path

Building the DOM tree

DOM (Document Object Model) tree is an object that represents a fully parsed HTML page. Starting at the root element <html>, nodes are created for every element / text on the page. Elements nested within other elements are represented as child nodes, and each node contains the full set of attributes for that element. For example, an element <a>will have an attribute hrefassociated with a node.

Take this document for example:

<html>  
<head>  
  <title>Understanding the Critical Rendering Path</title>
  <link rel="stylesheet" href="style.css">
</head>  
<body>  
  <header>
      <h1>Understanding the Critical Rendering Path</h1>
  </header>
  <main>
      <h2>Introduction</h2>
      <p>Lorem ipsum dolor sit amet</p>
  </main>
  <footer>
      <small>Copyright 2017</small>
  </footer>
</body>  
</html>  

The following DOM tree will be built from it:


Understanding the critical rendering path

The good news about HTML is that it can be executed in chunks. The document does not have to be fully loaded for the content to appear on the page. However, other resources such as CSS and JavaScript can block the page from rendering.

Building a CSSOM tree

The CSSOM (CSS Object Model) is an object that represents the styles associated with the DOM. It looks just like the DOM, but with appropriate styles for each node. It doesn't matter if the styles were explicitly declared or inherited.

In the file style.cssincluded in the previously mentioned document, we have the following set of styles:

body { font-size: 18px; }

header { color: plum; }  
h1 { font-size: 28px; }

main { color: firebrick; }  
h2 { font-size: 20px; }

footer { display: none; }

It will produce the following CSSOM tree:


Understanding the critical rendering path

CSS is considered a "blocking resource". This means that the Render tree (see below) cannot be built without a complete initial parsing of the CSS.

Unlike HTML, CSS cannot be used in chunks due to its cascading nature. The styles described in the document below can override and modify the styles defined earlier. So if we start using CSS styles before the stylesheet is parsed, we might run into a situation where the styles are being applied incorrectly. This means that in order to proceed to the next step, the CSS must be fully parsed.

CSS files block render only if they are applied. <link rel="stylesheet">can take a media attribute, in which we can specify any media expression to which the nested styles will refer. If, for example, we have a style sheet with a media attribute orientation:landscape, and we are viewing the page in portrait mode, then this resource will not be considered processing blocking.

CSS can also be "script blocking" because JavaScript files must wait for the CSSOM to build before being executed.

Running JavaScript

JavaScript is a blocking resource for the parser. This means that JavaScript blocks parsing of the HTML document itself.

When the parser reaches a tag <script>(it doesn't matter if it is internal or external), it stops, picks up the file (if it is external) and starts it. This is why, if we have a JavaScript file that references document elements, we must definitely place it after they appear.

JavaScript can be loaded asynchronously by specifying an attribute asyncto avoid blocking the parser.

<script async src="script.js">  

Render tree creation

The render tree is a collection of DOM and CSSOM. It is a tree that gives an idea of ​​what will ultimately be displayed on the page. This means that it only captures visible content and does not include, for example, elements that were hidden using a CSS rule display: none.

Using the examples of DOM and CSSOM presented above, the following Render tree will be built:


Understanding the critical rendering path

Layout generation

Layout is what determines the size of the document's visible area ( viewport ), which provides context for CSS styles that depend on it, such as percentages or viewport units.

The size of the viewport is determined by the meta tag found in the <head>document or, if no tag is present, the default viewport value of 980 pixels will be used.

For example, the most common value for this meta tag is a size that matches the width of the device.

<meta name="viewport" content="width=device-width,initial-scale=1">

If a user visits a web page from a device whose width is, for example, 1000 pixels, then the dimensions will be based on this value. Half of the visible area will be 500 pixels, 10 percent will be 100 pixels, and so on.

Rendering

Finally, in the rendering step, the page's visible content can be converted to pixels to appear on the screen.

The time this step will take depends on both the size of the DOM and what styles are being applied. Some styles take more effort to apply than others. For example, a complex gradient background image will take longer than a simple solid color background.

Putting it all together

To see how the critical rendering path happens, we can use the developer tools. In Chrome, this can be done in the "Timeline" tab (in Canary, and soon in stable versions of Chrome, the tab has been renamed to "Performance").

Let's take our HTML sample mentioned above (with the tag added <script>) as an example .

<html>  
<head>  
  <title>Understanding the Critical Rendering Path</title>
  <link rel="stylesheet" href="style.css">
</head>  
<body>  
  <header>
      <h1>Understanding the Critical Rendering Path</h1>
  </header>
  <main>
      <h2>Introduction</h2>
      <p>Lorem ipsum dolor sit amet</p>
  </main>
  <footer>
      <small>Copyright 2017</small>
  </footer>
  <script src="main.js"></script>
</body>  
</html> 

If we look at the Event Log for this page, we see the following:


Understanding the critical rendering path

  1. Send Request - GET request sent for index.html;
  2. Parse HTML and Send Request - Start parsing HTML and building the DOM. Send GET request for style.css and main.js;
  3. Parse Stylesheet - CSSOM generated for style.css;
  4. Evaluate Script - calculate (execute) main.js;
  5. Layout - generation of layout based on the value of the viewport meta tag;
  6. Paint - drawing pixels in the document.

Based on this information, we can make decisions to optimize the critical rendering path. I'll cover some of these techniques in future posts.


Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Scripting client side JavaScript, jqvery, BackBone

Terms: Scripting client side JavaScript, jqvery, BackBone