Behind the scenes of browser rendering
In this article, we are going to look at how a modern browser actually renders a web page. Imagine you open a browser and hit www.google.com. What happens behind the scenes ?
Lets understand it step by step.
First the browser to identify if what you entered in the address bar is a url or a search query. If it is a search query, it will send a request to the server to fetch the results.
But if its a url, then browser will extract the protocol, domain, path and query parameters from the url. DNS lookup will be performed to get the servers IP address. Once the IP address is obtained, the browser will establish a TCP connection with the server.
Once the connection is established, the browser will send a HTTP GET request of type document to the server. The server will then send back the document i.e the html code for the page back to browser.
Here's how the request looks like.
If you look at the response tab, you will see the html code for the page.
For the scope of this article, lets use following html code. You can try this code for yourself here - https://2357228.playcode.io/
<!DOCTYPE html>
<html>
<head>
<title>Simple Button Example</title>
<style>
#myButton {
padding: 10px 20px;
background-color: #f0f0f0;
border: 1px solid #ccc;
cursor: pointer;
}
#message {
display: none; /* Initially hidden */
margin-top: 20px;
font-size: 1.2em;
}
</style>
</head>
<body>
<button id="myButton">Click Me</button>
<div id="message"></div>
<script>
document.getElementById('myButton').addEventListener('click', function() {
document.getElementById('message').textContent = 'Hello, World!';
document.getElementById('message').style.display = 'block'; // Make it visible
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Simple Button Example</title>
<style>
#myButton {
padding: 10px 20px;
background-color: #f0f0f0;
border: 1px solid #ccc;
cursor: pointer;
}
#message {
display: none; /* Initially hidden */
margin-top: 20px;
font-size: 1.2em;
}
</style>
</head>
<body>
<button id="myButton">Click Me</button>
<div id="message"></div>
<script>
document.getElementById('myButton').addEventListener('click', function() {
document.getElementById('message').textContent = 'Hello, World!';
document.getElementById('message').style.display = 'block'; // Make it visible
});
</script>
</body>
</html>
Now that the browser has the html code, it will start the rendering process.
- Browser will parse the html code and creaet a DOM tree. This tree is a hierarchical representation of the html code.
DOM stands for Document Object Model. Every html element is represented as a node or object in the model. Every node has a parent, children and siblings. The root of the tree is the document node.
Here's how the DOM tree looks like for the above html code.
#document
|
+-- html
|
+-- head
| |
| +-- title
| | |
| | +-- "Simple Button Example" (Text Node)
| |
| +-- style
| |
| +-- "#myButton { ... } #message { ... }" (Text Node)
|
+-- body
|
+-- button
| |
| +-- "Click Me" (Text Node)
| |
| +-- id = "myButton" (Attribute Node)
|
+-- div
|
+-- id = "message" (Attribute Node)
|
+-- script
|
+-- "document.getElementById('myButton')..." (Text Node)
#document
|
+-- html
|
+-- head
| |
| +-- title
| | |
| | +-- "Simple Button Example" (Text Node)
| |
| +-- style
| |
| +-- "#myButton { ... } #message { ... }" (Text Node)
|
+-- body
|
+-- button
| |
| +-- "Click Me" (Text Node)
| |
| +-- id = "myButton" (Attribute Node)
|
+-- div
|
+-- id = "message" (Attribute Node)
|
+-- script
|
+-- "document.getElementById('myButton')..." (Text Node)
- The browser will then parse the css code and create a CSSOM tree. This tree is a hierarchical representation of the css code. Every css rule is represented as a node or object in the model.
Here's how the CSSOM tree looks like for the above html code.
CSSOM
|
+-- Rule: #myButton
| |
| +-- padding: 10px 20px
| +-- background-color: #f0f0f0
| +-- border: 1px solid #ccc
| +-- cursor: pointer
|
+-- Rule: #message
|
+-- display: none
+-- margin-top: 20px
+-- font-size: 1.2em
CSSOM
|
+-- Rule: #myButton
| |
| +-- padding: 10px 20px
| +-- background-color: #f0f0f0
| +-- border: 1px solid #ccc
| +-- cursor: pointer
|
+-- Rule: #message
|
+-- display: none
+-- margin-top: 20px
+-- font-size: 1.2em
- The browser will then combine the DOM and CSSOM trees to create a render tree.
Here's how the render tree looks like for the above html code.
Render Tree (Initial State)
|
+-- body (display: block)
|
+-- button (display: inline-block, padding: 10px 20px, background-color: #f0f0f0, border: 1px solid #ccc, cursor: pointer)
| |
| +-- "Click Me" (Text Node)
|
+-- div (display: none, margin-top: 20px, font-size: 1.2em)
Render Tree (Initial State)
|
+-- body (display: block)
|
+-- button (display: inline-block, padding: 10px 20px, background-color: #f0f0f0, border: 1px solid #ccc, cursor: pointer)
| |
| +-- "Click Me" (Text Node)
|
+-- div (display: none, margin-top: 20px, font-size: 1.2em)
Once the user clicks on the button, the browser will update the render tree.
Render Tree (After Button Click)
|
+-- body (display: block)
|
+-- button (display: inline-block, padding: 10px 20px, background-color: #f0f0f0, border: 1px solid #ccc, cursor: pointer)
| |
| +-- "Click Me" (Text Node)
|
+-- div (display: block, margin-top: 20px, font-size: 1.2em)
|
+-- "Hello, World!" (Text Node)
Render Tree (After Button Click)
|
+-- body (display: block)
|
+-- button (display: inline-block, padding: 10px 20px, background-color: #f0f0f0, border: 1px solid #ccc, cursor: pointer)
| |
| +-- "Click Me" (Text Node)
|
+-- div (display: block, margin-top: 20px, font-size: 1.2em)
|
+-- "Hello, World!" (Text Node)
-
The browser will then lay out the elements on the page. This is called layout or reflow.
-
The browser will then paint the elements on the page. This is called painting.
-
The browser will then display the page to the user.
Here's how our simple page looks like.
