Browser Rendering Mechanism
by Elliott Chen, a developer
The rendering mechanism of Chrome stands as a true masterpiece in the world of web browsers, a work of art that speaks volumes through its performance and precision. It transcends the need for introductions, silently weaving a symphony of rendering processes, from parsing and styling to layout and compositing. Its meticulous orchestration of threads and layers harmonizes with GPU acceleration, ensuring a symphony of speed and efficiency. In the realm of web rendering, Chrome's mechanism is a masterpiece that paints web content onto the canvas of our screens with elegance and finesse.
Rendering nodes
In a nutshell, think it as a render function
that takes HTML
as a argument, and this function retures pixelated info, period.
function render(html) {
// 1st row: ....
// 1st col: ....
return pixels
}
Take a look at the follow illustration first:
When we make a request via HTTPS, the internet process of Chrome dispatches a thread to do the task. It sends a doc of HTML, the format as string (AKA the source code of any web page) as a rendering task to the message queue. Because of the mechanism of eventloop, the main thread of Rendering grabs the task from the message queue and starts to render it.
There are 8 steps of the entire renderer, together they are a pure beauty of a Well-organized assembly line.
1.0 Parse HTML
First of the first, parsing HTML from a string to a tree structure AKA DOM, big bro doing this step is extremely important, making the little bros' lives easier, so the little bros don't need to deal with strings.
1.1 Encounter CSS link while parsing HTML
What if there is a CSS link while parsing HTML? Should renderer stops immediately and parses CSS instead? Let's take a look:
In the process of parsing HTML, in order to achieve max efficiency, as well as making it non-blocking, the preparser thread will check the CSS link and ask the internet thread to start loading CSS. After the loading is done, the preparser thread will pick up the preparser task and does a scan for rendering thread to parse, finally the rendering thread will do the rest of parsing.
1.2 Encounter JS link while parsing HTML
What about JavaScript? Let's take a look:
Notice the distinctions? When we compare it to a CSS pre-parser, you might wonder why on earth the rendering thread has to pause and wait for JavaScript to be executed. The reason behind this is quite straightforward: JavaScript has the potential to dynamically alter the DOM.
2.0 Calculate Style
Browser calculates styles by parsing CSS code, matching selectors to HTML elements, computing specificity to resolve conflicts, and factoring in inheritance. This cascade and specificity calculation process culminates in the determination of computed styles for each element, including values for all CSS properties. These computed styles are vital for the subsequent layout and rendering of web pages, ensuring that elements are displayed correctly and in accordance with the defined styles.
There is one more thing of computed style worth knowing, whatever styles we like to write isn't final to browser, the computed style is.
3.0 Layout
Layout, in the context of web development and browser rendering, refers to the process by which a web browser determines the size, position, and arrangement of all HTML elements on a web page. It's also known as the "reflow" process. During layout, the browser calculates the exact dimensions of each element based on its content, padding, borders, and margins, as well as the styles defined in the CSS. This information is essential for positioning elements on the screen and determining how they interact with one another. Efficient layout calculations are crucial for maintaining smooth and responsive user experiences on web pages, especially when elements change dynamically due to user interactions or data updates.
3.1 DOM Tree and Layout Tree
Pay attention tho, DOM Tree and Layout Tree aren't corresponding in a lot of ways.
CSS properties like display:none
will not show in layout tree, and pseudo-classes will not show in DOM tree.
4.0 Layer
Layers in Chrome's rendering process are a key optimization technique that enhances performance by isolating and compositing web content efficiently. They are instrumental in achieving smoother animations, improved scrolling, and faster rendering of web pages.
CSS properties like transform
and opacity
will affect the result of layer.
5.0 Paint
Indeed, after the process of layering, Chrome dispatches instructions for tiling. This step represents one of the final actions carried out by the main rendering thread.
5.1 Paint is the last step of main thread
Once the tiling instructions are prepared, the main thread relinquishes control of subsequent tasks to other threads. This multi-threaded approach is designed to optimize performance and responsiveness in rendering web content, with the reasons for this delegation becoming clearer as the rendering process continues.
6.0 Tiling
To further optimize rendering, the browser may break the rasterized content into smaller tiles. This allows for incremental rendering, meaning that only the visible portion of the page needs to be rasterized and displayed, improving performance and responsiveness.
In this step, Chrome cuts every layer into smaller boxes.
6.1 Compositor thread for tiling
6.2 Threads and compositors in activity monitior
7.0 Rasterization
Rasterization takes the paint commands and converts them into a grid of pixels. It determines how the visual content should be mapped to the screen's pixel grid, multiple threads are often used for rasterization, and they prioritize handling blocks or tiles that are closer to the viewport (visible area). This strategy is known as Viewport-First Rendering.
Taking tiles and rasterize them to bitmaps.
7.1 GPU rasterizes it
In this step, GPU process accelerates rasterization.
7.2 GPU process in Chrome's activity monitior
8.0 Draw
The final stage in the rendering process is rendering itself. The compositing thread receives bitmap information for each layer and block, creating a set of "quads" for each one. These quads specify where each bitmap should be positioned on the screen, taking into account transformations like rotation and scaling. Importantly, these transformations occur in the compositing thread and are unrelated to the rendering main thread, which contributes to the efficiency of transformations. The compositing thread then submits the quads to the GPU process. The GPU process generates system calls and sends them to the GPU hardware, ultimately completing the rendering process and displaying the content on the screen.
Since Chrome uses a security feature called sandboxing during the rendering process to enhance security and protect the overall system from potential threats that may arise from rendering untrusted web content. The sandboxing mechanism in Chrome operates at various levels, including during the rendering process. That's why Quad needs to stop and pass it to the GPU process to handle.
Full Process
Let's take a look at this illustration of Full Process:
Reflow in full process
Repaint in full process
Transform in full process
That's why transform is always good to use, and reflow costs the most in terms of optimization.
Once again, Chrome's rendering mechanism is a masterpiece of art, with all the respect, salute.
P.S.