The trees built in the parsing phase (DOM, CSSOM) are combined into something called the
render tree. This is used to compute the layout of all visible elements that will be painted to the screen in the end. The purpose of the
render tree is to make sure the content of the page will paint the elements in the correct order. It will be serverd as input to the painting process that will display the pixels on the screen.
The DOM and the CSSOM are created using the HTML and the CSS files. Both of these files hold different types of information and the trees are different structures, so how does the render tree gets created?
COMBINING THE DOM WITH THE CSSOM
- The browser will start doing its magic at the root of the
DOM treeand traverse every visible node. Some of the nodes, like script or meta tags are not visible, so they are ignored. There are also nodes that will be hidden with the use of CSS (the
display: "none"property for example) and they will also be ignored. We are only interested in the visible nodes because only they matter for the input on the screen.
- For each visible node that's found in the DOM, the coresponding rules will be found in the CSSOM and they will be applied.
The result of these steps will be a
render tree that contains all visible nodes, with content and styles.
THE LAYOUT (REFLOW) STAGE
The render tree holds information on which nodes are displayed along with their computed styles, but not the dimensions or location of each node.
What needs to be done next is calculate the exact position of those nodes within the viewport of the device (inside the browser window) and their size. This is the stage called
layout (in Chrome, Opera, Safari and Internet Explorer) or
reflow (in Firefox) but they mean the same thing. The browser starts this process at the root of the render tree and traverses it.
The reflow step doesn't happen only once, but every time we change something in the DOM that affects the layout of the page, even partially. Examples of situations when the positions of the elements is recalculated are:
- adding or deleting elements from the DOM
- resizing the browser window
- changing the width, the position of an element or floating it
Let's get a very basic example of HTML, with some CSS applied inline:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1" /> <title>Reflow</title> </head> <body> <div style="width: 100%; height: 50%"> <div style="width: 50%; height: 50%">This is the reflow stage!</div> </div> </body> </html>
The above code just says that inside the viewport we should have two
divs, where the second one is nested inside the first. The parent div takes up 100% of the viewport and the second 50% of the parent. This will look something like this:
The output of this process is a
box like model which captures exactly where each element needs to be on a screen and its size. After this step is finished, the output is ready to be passed to the next step called the
THE PAINTING (REPAINTING) STAGE
After the browser decides which nodes need to be visible and calculates their position in the viewport, it's time to paint them (render the pixels) on the screen. This phase it is also known as the
rasterization phase, where the browser converts each box calculated in the layout phase to actual pixels on the screen.
Just like the layout stage, the painting stage doesn't happen just once but every time we change something in the appearance of the elements on the screen. Examples of these situations are:
- changing the outline of an element
- changing background color
- changing opacity or visibility
Painting means the browser needs to draw every visual part of an element to the screen, including text, colors, borders, shadows, and replaced elements like buttons and images and it needs to do it super quickly. To ensure repainting can be done even faster than the initial paint, the drawing to the screen is generally broken down into several layers. If this occurs, then compositing is necessary.
LAYERING AND COMPOSITING
Traditionally, web browsers relied entirely on the CPU to render web page content. But nowadays even the smallest devices have performant GPUs, so the attention has turned on finding ways to use this piece of hardware to achieve better performance.
Compositing is a technique to separate parts of a page into layers, painting them separately and composite as a page in a separate thread called the compositor thread. When sections of the document are drawn in different layers, overlapping each other, compositing is necessary to ensure they are drawn to the screen in the right order and the content is rendered correctly.
Generally, only specific tasks get redirected to the GPU and those are the tasks that can be handled by the compositor thread alone.
In order to find out which elements needs to be on which layer, the main thread walks through the layout tree and creates the
layer tree. By default, there's only one layer (and how these layers are implemented is browser specific) but we can find the elements that would trigger a repaint and create a separate layer for each of them. This way, the repainting should not be applied to the whole page and in addition, this process will use the GPU.
If we want to hint to the browser that ceratain elements should be on a separate layer, we can use the
will-change CSS attribute. There are actually specific properties and elements that signal the creation of a new layer. Some of these are
<canvas>, and any element which has the CSS properties of
opacity, a 3D
will-change and a few others. These nodes will be painted onto their own layer, along with their descendants.
KEEP IN MIND
Both of the operations discussed above,
reflow and repaint, are expensive, especially on devices with low processing power like phones. That's why when dealing with DOM changes we should try to optimze them (I will talk more about this in one of the future articles in my
DOM series). Some actions will trigger a repaint only and some actions both a reflow and a repaint.
Top comments (10)
Excellent blog!! But where in the flow diagram is script(JS)? When JS loads, the browser stops parsing HTML and formation of any new node because JS will also impact the DOM, which may cause confusion. This above process is also known as the Critical rendering path (CRP).
😀 ah. Keep posting good stuff 👍🏻
Thank you Nitin.
Extremely important to know and underrated!
Thank you, I am glad you found it useful.
This is the right URL that I have been looking for last three days, how HTML, CSS and JS run in the browser to display that webpage behind the sense.
I like very much what you did and explained. Very proud of you as a writer on www.
Go Ahead. Thanks a lot Arika. May Allah protects you JIT.
I wanna tell you something, I want to be like you.
Basic Principles, HTML, CSS, JS, React, as a front end developer and keep moving to full stack via node, MongoDB. Big Dreams Pal.
Thank you Nassarzakaria.
Fantastic write up thats a good way to go about explaining it.