Stonks guide to Critical Rendering Path
Let's Understand what is CRP and how it works!
Before a page is loaded on the screen there are certain sets of events happening behind this screen, But first, let's understand what is Critical Rendering Path?
It is a sequence of steps the browser goes through in order to convert HTML, CSS and Javascript into pixels on the screen.
All of these happen in a sequence and that follows as:
Before we move forward let me quickly explain how do resources load:
- Request for a webpage or app starts with an HTML request and the server returns the HTML response in headers and data.
- Then the Browser begins to parse the HTML, converting the received bytes to the DOM Tree
- It also initiates the request every time it comes across external resources like stylesheets, scripts, embedded images etc.
- But here some requests block the parsing of the HTML ex. scripts
- So parsing is halted until the blocking requests are handled after that the HTML is parsed completely, DOM gets build.
- And by the point, it comes to an end it constructs the CSSOM.
- After DOM and CSSOM are completely ready, render tree reads computes styles for all visible content.
- After the render tree is completed the layout occurs defining the location & size of all the render elements of the tree.
- Once all this is completed the page is rendered or painted on the screen
To much text to digest but trust me stick for a while by the end of the blog, you will understand CRP.
let's talk about DOM or Document Object Model
This is a basic HTML file that will use here as example for understanding how DOM is created!
- DOM construction works in
incrementing manner.
- Network Call is made → We receive our packet as in the partial HTML → we can start constructing the DOM.
- But we tend to see white screen as we haven't received entire HTML yet!
- Remember me talking about how DOM is constructed ?
- Let me explain what happens here clearly!
- We get Bytes of Data → they are interpreted as characters → browser starts creating tokens → nodes are created out of these tokens.
- Single DOM node starts with
StartTag
token and ends withEndTag
token. - These nodes contain all the relevant information about the HTML element.
- The information is described using tokens and nodes are connected to DOM tree using token hierarchy.
- When there are nested tokens we have a node inside node.
- Note: greater the number of nodes, the longer the following events in the critical rendering path will take.
- Now if you are wondering how are these nodes made they are made using specific HTML5 parsing algorithm which gives entire constructed tree.
When parsing the html it will come across other files such as in our above code snippet there is stylesheet in the tag and as soon as it sees stylesheet it will make HTTP request and in the meanwhile, the HTML will be parsed and DOM is being constructed .
And once the html is parsed DOM is constructed. but there is still nothing on the screen yet cause we don't have style for html we parsed if we do so we tend to see some ugly structure of frames around the screen which are called as [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content)
also called as flash of unstyled components!
CSSOM or CSS Object Model:
- Now when the DOM is constructed, the request for stylesheet was made the bytes have arrived.
- CSSOM contains all the styles of the pages.
- It is similar to DOM but different.
- While DOM works in an incremental manner CSSOM doesn't.
- CSS is render-blocking: the browser blocks page rendering until it receives and processes all of the CSS. CSS is render-blocking because rules can be overwritten, so the content can't be rendered until the CSSOM is complete.
- So the CSS has its own set of rules for identifying valid tokens. In CSS C stands for
Cascade
. - CSS rules
cascade down
. - It is not a built-in render tree because there might be subsequent properties that can override each other there the CSS is first completely parsed and then only brought on the screen.
- nested selectors or more specific selectors are slower as compared to the less specific selectors.
example.
.foo{ } //is faster as compared to .foo .bars{ }
- because in such cases it has to again walk back to the specific DOM node.
- Ways through which you can optimize CSS is by minification and separating deferred CSS into non-blocking requests by using media queries.
Render Tree:
Once the DOM & CSSOM are created,
- Then using the DOM tree and CSSOM is built we tend to get a Hybrid tree which has all the CSS applied on their respective DOM elements.
- Render tree is formed by checking every node from the root and determine which CSS rules are attached.
- If in case there is any
display: none
property set on an element, neither it nor any of its descendants, are in the render tree.
Layout:
Once the render tree is ready, Browser starts working on the Layout.
What is Layout?
- Layout is dependent on the size of screen. The layout step determines where and how the elements are positioned on the page, determining the width and height of each element, and where they are in relation to each other.
- The viewport meta tag defines the width of the layout viewport, impacting the layout. Without it, the browser tends to use default viewport width, which by-default for full-screen browsers is generally 960px.
- On default full screen browsers, ex. mobile's browser, by setting
<meta name="viewport" content="width=device-width">
, the width will be the width of the device and not the default viewport width. - The device width changes as the user changes the view orientation ie., landscape or portrait. Layout happens every time a device view orientation is changed or browser is resized.
- Layout performance is also impacted by DOM.
- The greater the number of nodes the longer that layout takes.
- We can also the see how long does the Layout take in Chrome dev tools.
Painting:
What is painting?
- Painting is also referred to as rasterizing.
- Painting is the last step in this process where the painting is responsible for painting or filling the pixels onto the screen.
- The entire screen is painted Onload.
- After the screen is loaded only the impacted areas are repainted, as browsers are advanced enough to repaint the minimum area required.
- Painting time depends on what kind of updates are getting applied to the render tree.
- Painting is a very fast process & couldn't be always the right place in terms of improving the performance.
This is all for the major understanding of CRP, but now let's understand how does Javascript gets involved in the entire process!
The Big Man of the Game:
- It's all because of the javascript that we are able to do a lot of stuff on the web.
- But this is where a lot of complexity increases Javascript can query in the DOM, access CSS properties applied on specific elements or change it or modify a specific element!
- So let's assume we want to write anything using javascript inside we would do it using
document.write('CRP')
we may want to write anything inside the DOM string, tag or any arbitrary character for that matter. - Hoping you remember how HTML is parsed but then let's assume there is a script tag in between when executed we have said that we are going to write a bunch of new HTML.
- But then whenever any such script tag is encountered the parsing of HTML is stopped as the browser doesn't know what changes the script would do, so the script is fetched completely, executed and then we proceed to parse the remaining HTML.
- One thing to observe here is that it basically blocks everything in the Browser ie., HTML parsing and etc.
- This is why we always see that CSS is at the top of the file and script is at the bottom which helps in not blocking a lot of the parsing.
- This can be better Tackled by using the async keyword in the script tag what async does is it basically the script is downloaded in the background and is executed when the script is ready whereas in traditional script tag it tends to block the parsing until the script is fetched and executed
-Below Image shows how the normal script tag works
-Below Image shows how the async works
So after looking and understanding at everything we realize that sending the only required HTML, not loading the JS that may trigger changes in CSS before them or using async tag.
This sums up the Basic and clear understanding as a beginner, feel free to share your thoughts and improvements around the blog.