Domain name and hit Enter. Then?
De-mystifying the science behind humankind's greatest invention.
Ever wondered what happens when you type "xyz.com" in your browser's address bar and it answers with the exact page you want? Ya, that's no magic.
There are a series of processing steps that are run by the browser in order to paint actual pixels on your screen. In this article, I'm going to give you a very high-level overview of how a browser renders a webpage through those steps.
So, Let's get started! 🚀
Finding The Required Assets
The first step of navigating to a web page is to identify where the assets, such as stylesheets, JS files, images, etc, reside. If the user had already visited the website, the browser engine will check its local browser cache where the recently visited website's assets are saved.
Now, if the cache has expired or the user is completely new to the site, the browser will send a DNS query to a DNS server to obtain the IP address associated with the domain name. This process is called "DNS lookup". Using the IP address, the browser can connect to the web server. This will allow it to request the HTML file and other resources that make up the website.
Upon receiving the HTML file, the browser will run through a lifecycle to provide the final output. It is referred to as Critical Rendering Path (CRP).
Parse HTML and Build The DOM
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>XYZ</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<p>
Hello
<span>World</span>
</p>
<div>xyz</div>
<script src="./script.js"></script>
</body>
</html>
As the browser receives the raw bytes of the above HTML markup, it needs to convert them into a character format according to its specified encoding(e.g. UTF-8).
Once the above process has been completed, The browser converts strings of characters and emits tokens from it. This process is done by the HTML Tokeniser.
While this tokenization continues, there’s another process that is consuming the tokens and converting them into Node objects.
The Nodes all together form a tree-like structure which we call the Document Object Model or simply the DOM. It is a fully parsed representation of the HTML markup.
Parse CSS AND Build The CSSOM
While the browser incrementally constructs the DOM, it might encounter a tag that references an external resource. The browser immediately fetches that external entity. Here we encountered the <link />
tag for a styles.css
file.
html {
font-size: 62.5%;
}
body {
font-size: 1.4rem;
width: 100%;
}
p {
width: 50%;
color: red;
}
span {
display: none;
}
p span {
display: block;
}
Once we receive the above CSS, it will start building the CSSOM which is somehow quite similar to the previous process.
Here the browser has to identify the correct token i.e html{ font-size: 62.5%; }
→ html
token and CSS have their own set of rules to apply styles on the target nodes. A few of them applied here are :
CSS rules "cascade down" i.e. you can see from the below image that the
font-size
of body which is1.4rem
has been passed down to its children.Specificity plays a huge role in resolving conflicts and attaching the correct styles by adding scores to selectors.
Taking reference from the above code, element selectors are given 1 point of specificity. Hence: span => 1, p span => 1 + 1 =2 i.e. p span > span.
The span inside the p tag will have
display: block
but the spans outside the p tag will be set todisplay:none
Construction of the Render Tree
In this phase of CRP, we merge the DOM and CSSOM to form the Render tree. The browser ignores certain types of content and elements that do not affect the visible layout of the page to build a more efficient and accurate render tree.
Some HTML elements, such as <script />
and <meta />
tags, do not possess any visual output on the screen and are therefore ignored while building the render tree. Elements that are set to display: none
in CSS are not included in the Render tree either.
Calculating Layouts
Once the Render tree has been constructed, the browser needs to calculate where the elements are to be placed on the screen along with their dimensions. This phase is also called the Layout phase or “Reflow”.
The output of the layout process is to generate the Box Model. Here all the relative measurements are converted to absolute pixels.
Let's consider our device width to be 650 px and now in our CSS file we have mentioned the width of our body to be 100% hence the percentage being a relative unit will allow the body to take up 100% of the device width and the final calculated width will be 650px. A similar rule will be applied to its children if it uses percentage units but it will be relative to its parent.
Paint and Composite
Painting is the process of filling in pixels. All the text colors, images, borders, shadows, and other visual effects of a DOM element are added in this phase. This process gets completed by generating multiple layers. This technique is known as "Layered painting". Based on the content and visual elements of the page, the browser divides the page into multiple layers. Each layer is then painted separately. It can now reuse the painted layers rather than having to repaint the entire page each time the page is updated.
The final step of the Critical rendering path is to bring all the layers into one layer in the correct order and produce the final output on the browser screen. This process is called Compositing.
Bingooo. There you go..... Oh, wait! we have a <script />
tag in our markup. Our app is more than just a static page! 🤯
JavaScript Execution and Interactivity
It depends on when and how JavaScript resources are loaded to determine when parsing and execution of JavaScript will occur. As you can see, we added our script tag to the end of our body tag. Therefore, all the above content is parsed, but there's a catch. We have set our div tag to display: none
using JavaScript.
const div = document.querySelector("div");
div.style.display = "none";
When you add interactivity to your app, the pipeline looks similar to the below image.
So, now our browser will quickly recalculate the styles by ignoring the div and finally generate our new Render Tree.
After that, it will directly go to Paint skipping the Layout phase because we didn't change any dimensions or positions here, and then finally Composite to render the final output.
And Boom. You have a fully rendered webpage on your browser screen ✨
Conclusion
By optimizing the Critical Rendering Path, you can improve the performance and UX of your web pages. A key component of the Javascript Framework's ecosystem is to optimize the CRP, especially the reflow and repaint, which is why concepts like Virtual DOM, batching, etc have been introduced.
Visit https://web.dev/critical-rendering-path-page-speed-rules-and-recommendations to know more about how to optimize the CRP.
Happy Web Engineering! 💫