Browser Rendering Process
Recently read a few articles on the principle of the browser, the browser rendering process has a more systematic understanding, here is a brief summary and by the way under the cliché rearrangement and repaint is how to go.
First, create a complete rendering flowchart
Combined with the above figure, a complete rendering process can be roughly summarized as follows:
The rendering process converts HTML content into a readable DOM tree structure.
- The rendering engine converts CSS style sheets into styleSheets that the browser can understand, and calculates the style of DOM nodes.
Create a layout tree and calculate the layout information of elements.
Layer the layout tree and generate a hierarchical tree. - Generate a draw list for each layer and submit it to the compositing thread.
- The compositing thread divides the layer into tiles and converts the tiles into bitmaps in the pool of grating threads.
- The compositing thread sends the DrawQuad command to the browser process.
- The browser process generates pages based on DrawQuad messages and displays them on the display.
For the first few processes, in fact, there is nothing to say in terms of function, and everyone understands, but if you specifically say how to achieve it, you can open a new blog, such as how html-parser converts html doc into DOM tree and so on.
So for the previous few processes, we will only briefly mention them.
The role of each step in the rendering process
Building the DOM tree
Why build a DOM tree?
This is because the browser cannot directly understand and use HTML, so it needs to convert HTML into a structure that the browser can understand - DOM tree.
However, we still don’t know the style of the DOM node. To make the DOM node have the correct style, this requires style calculation.
Style calculation (Recalculate
The purpose of style calculation is to calculate the specific style of each element in the DOM node. This stage can be roughly divided into three steps to complete.
Put
There are three main sources of CSS styles:
External CSS files referenced by link
Css inside the ‘< style >’ tag.
element style attribute embedded css
Like HTML files, browsers cannot directly understand the CSS styles of these plain text, so when the rendering engine receives the CSS text, it will perform a conversion operation to convert the CSS text into a structure that the browser can understand - styleSheets.
Convert property values in style sheets to standardize them
1 |
|
You can see that there are many property values in the CSS text above, such as 2em, blue, bold. These types of values are not easy to be understood by the rendering engine, so all values need to be converted into standardized calculation values that are easy for the rendering engine to understand. This process is to standardize the property value.
Calculated
Layout phase
Now, we have the DOM tree and the styles of the elements in the DOM tree, but this is not enough to display the page because we don’t know the geometric position information of the DOM elements yet. Then we need to calculate the geometric position of the visible elements in the DOM tree. We call this calculation process layout.
Chrome need to complete two tasks during the layout phase: create the layout tree and calculate the layout.
Create a layout tree
In order to build the layout tree, the browser generally completes the following tasks:
traverse all visible nodes in the DOM tree and add these nodes to the layout tree;
Invisible nodes are ignored by the layout tree, such as all content below the head tag, and the element body.p.span, which is not included in the layout tree because its attribute contains dispaly: none.
Layout calculation
Now we have a complete layout tree. Next, we need to calculate the coordinate positions of the layout tree nodes.
Stratification
Now that we have the layout tree and the specific position information of each element has been calculated, is it time to start drawing the page? The answer is still no.
Because there are many complex effects in the page, such as some complex 3D transformations, page scrolling, or using z-indexing to do z-axis sorting, etc. In order to achieve these effects more conveniently, the ** rendering engine also needs to generate special for specific nodes layer, and generate a corresponding layer tree ** (LayerTree). If you are familiar with PS, I believe you will easily understand the concept of layers, which are superimposed together to form the final page image.
** The browser page is actually divided into many layers, and these layers are superimposed to form the final page **
Usually, not every node in the layout tree contains a layer. If a node does not have a corresponding layer, then this node belongs to the parent node’s layer.
So what conditions need to be met before the rendering engine will create a new layer for a specific node? Usually, elements that meet any of the following two points can be promoted to a separate layer.
First, elements with the Cascading Context attribute are promoted to a separate layer.
Second, the places that need to be clipped will also be created as layers.
Layer rendering
After completing the construction of the layer tree, the rendering engine will draw each layer in the layer tree, so let’s take a look at how the rendering engine implements layer drawing?
Imagine if you were given a piece of paper and asked to paint the background blue, then draw a red circle in the middle, and finally draw a green triangle on the circle. How would you do it?
Usually, you will break down your drawing operation into three steps:
- Draw a blue background;
Draw a red circle in the middle.
- Draw a green triangle on the circle again.
The rendering engine implements layer drawing similarly, splitting the drawing of a layer into many small drawing instructions, and then forming a list of instructions to be drawn in order
Raster operation
The drawing list is only a list used to record the drawing order and drawing instructions. In fact, the drawing operation is completed by the compositing thread in the rendering engine.
When the drawing list of the layer is ready, the main thread will commit the drawing list to the compositing thread, so how does the compositing thread work next?
Then we need to first take a look at what a viewport is
Usually a page may be very large, but the user can only see a part of it. We call this part that the user can see the viewport.
In some cases, some layers can be very large. For example, there are pages that you need to scroll for a long time to scroll to the bottom using the scroll bar, but through the viewport, the user can only see a small part of the page, so in this case, It would be too expensive to draw all the contents of the layer, and it would not be necessary.
For this reason, the compositing thread divides the layer into tiles, which are usually 256x256 or 512x512 in size, as shown in the image below:
Then the compositing thread will preferentially generate bitmaps according to the tiles near the viewport. The actual operation of generating bitmaps is performed by rasterization. ** The so-called rasterization refers to converting tiles into bitmaps. The tile is the smallest unit of rasterization execution **. The rendering process maintains a rasterized thread pool, and all tile rasterization is performed in the thread pool. The operation mode is shown in the following figure:
Synthesis and display
Once all tiles have been grated, the compositing thread generates a command to draw the tiles - “DrawQuad” - and then submits the command to the browser process.
There is a component called viz in the browser process, which is used to receive the DrawQuad command sent by the synthetic thread, and then draw the page content into memory according to the DrawQuad command, and finally display the memory on the screen.
At this point, after this series of stages, the written HTML, CSS, JavaScript and other files will display beautiful pages through the browser.
Rearrangement, repaint, compositing
Updated geometric properties of elements (rearranged)
As can be seen from the above figure, if you modify the geometric position properties of an element through JavaScript or CSS, such as changing the width, height, etc., then the browser will trigger a relayout and a series of sub-stages after parsing. This process is called rearrangement. Undoubtedly, rearrangement requires updating the complete rendering pipeline, so the overhead is also the largest.
Update drawing properties of elements (repaint)
Next, let’s take a look at repainting, such as changing the background color of some elements through JavaScript, how will the rendering pipeline be adjusted? You can refer to the following image:
As can be seen from the figure, if the background color of the element is modified, the layout stage will not be executed, because it does not cause the transformation of the geometric position, so it directly enters the drawing stage, and then executes a series of sub-stages. This process is called repaint. Compared to the rearrangement operation, the redrawing eliminates the layout and layering stages, so the execution efficiency will be higher than the rearrangement operation.
Direct synthesis stage
So what happens if you change a property that neither layouts nor draws? The rendering engine will skip layout and drawing and only perform subsequent compositing operations. We call this process compositing. For details, please refer to the following figure:
In the above figure, we use the CSS transform to achieve the animation effect, which can avoid the rearrangement and repaint stages and directly perform the compositing animation operation on the non-main thread. This is the most efficient, because it is composited on the non-main thread and does not occupy the resources of the main thread. In addition, the two sub-stages of layout and drawing are avoided, so compared with repaint and rearrangement, compositing can greatly improve rendering efficiency.
Note:
The pictures in this article are all from Geek Time “Browser Working Principle and Practice”