When you see this title, you will definitely think of this divine article "How Browsers Work". This article explains many details of browsers in great detail, and it has also been translated into Chinese. Why do I still want to write one? Because of two reasons,
1) This article is too long and the reading cost is too high to be read in one sitting.
2) After spending a lot of effort reading this article, I can understand a lot, but it doesn’t seem to be of much help to my work.
So, I am going to write this article to solve the above two problems. I hope you can finish reading it on your way to work or while sitting on the toilet, and learn something from it that you can use at work.
Stop talking nonsense, let’s look at a picture first:
From the above picture, we can see that A few things:
1) The browser will parse three things:
2) After the parsing is completed, the browser engine will pass the DOM Tree and CSS Rule Tree to construct the Rendering Tree. Note:
3) Finally, draw by calling the API of the operating system Native GUI.
HTML’s DOM Tree parsing is as follows:
1
2
3
4
5
6
7
8
9
10
11
12
< html >
< html >
< head >
< title >Web page parsing title >
head >
< body >
< ;/ div >
body >
html >
The above HTML will be parsed It looks like this:
Here is another case with SVG tags.
CSS parsing
CSS parsing is probably as follows (the following mainly talks about how Gecko is played in Firefox). Suppose we have the following HTML document:
1
2
3
4
5
6
7
8
9
< doc >
< title > A few quotes title >
< para >
Franklin said that < quote >"A penny saved is a penny earned." quote >
< ;/ para >
< para >
FDR said < quote >"We have nothing to fear but < span >fear itself. span > " quote >
para >
doc >
So the DOM Tree looks like this:
Then our CSS document looks like this of:
1
2
3
4
/* rule 1 * / doc { display: block; text-indent: 1em; }
/* rule 2 */ title { display: block; font-size: 3em; }
/* rule 3 * / para { display: block; }
/* rule 4 */ [class="emph"] { font-style: italic; }
So our CSS Rule Tree will look like this:
Note that the 4th rule in the picture appears twice, once independently and once in the sub-section of rule 3. point. Therefore, we can know that establishing CSS Rule Tree needs to be based on DOM Tree. CSS matching DOM Tree mainly parses the Selector of CSS from right to left. Many people think that this will be faster, but in fact it is not necessarily the case. The key depends on how our CSS Selector is written.
Note: CSS matching of HTML elements is a rather complex matter and has performance issues. Therefore, you will see many people telling you in many places that the DOM tree should be small, CSS should use id and class as much as possible, and do not overlay it...
Through these two A tree, we can get a called Style Context Tree, which is as follows (Attach the CSS Rule node to the DOM Tree):
So, Firefox basically uses CSS The CSS Rule Tree is generated by parsing, then the Style Context Tree is generated by comparing the DOM, and then Firefox is completed by associating the Style Context Tree with its Render Tree (Frame Tree). Note: Render Tree will remove some invisible nodes. And the so-called Frame in Firefox is a DOM node, don’t be confused by its name .
Note: Unlike Firefox, which uses two trees to do this, Webkit also has a Style object, which directly stores the Style object in the corresponding DOM node.
The process of rendering is basically as follows (the four steps in yellow):
Note: There are many connecting lines in the process in the above figure, which means that dynamic modification of DOM attributes or CSS attributes by Javascript will cause re-Layout. Some changes will not, such as those arrows pointing to the sky. For example, the modified CSS rule will not is matched to, etc.
There are two important concepts to talk about here, one is Reflow and the other is Repaint. These two are not the same thing.
The following is a video of Layout/reflow when opening Wikipedia (Note: HTML will also do a reflow during initialization, called initial reflow), you can feel it:
The cost of Reflow is much higher than that of Repaint. Each node in the DOM Tree will have a reflow method. The reflow of a node is likely to lead to the reflow of child nodes, or even parent nodes and sibling nodes. It may not be a problem on some high-performance computers, but if reflow occurs on a mobile phone, then this process is very painful and power-consuming.
Therefore, the following actions are likely to be relatively expensive.
Note: display:none will trigger reflow, while visibility:hidden will only trigger repaint, because no position change is found.
Tell me a few more words about scrolling. Generally speaking, if all the pixels on our page will scroll when scrolling, then there is no performance problem, because our graphics card is not suitable for this kind of full-screen pixels. The algorithm for moving up and down is very fast. But if you have a fixed background image, or some elements do not scroll, and some elements are animated, then this scrolling action will be a very painful process for the browser. You can see how poorly a lot of these pages perform when scrolling. Because scrolling may also cause reflow.
Basically, there are several reasons for reflow:
Okay, let’s look at an example:
1
2
3
4
5
6
7
8
9
10
11
12
var bstyle = document.body.style; // cache
bstyle.padding = "20px" ; // reflow , repaint
bstyle.border = "10px solid red" ; // Reflow and repaint again
bstyle.color = "blue" ; // repaint
bstyle.backgroundColor = "#fad" ; // repaint
bstyle.fontSize = "2em" ; // reflow, repaint
// new DOM element - reflow, repaint
document.body.appendChild(document.createTextNode( 'dude!' ));
Of course, our browser is smart. It will not reflow or repaint every time you change the style like the above. Generally speaking, the browser will accumulate a batch of such operations and then perform a reflow, which is also called asynchronous reflow or incremental asynchronous reflow. However, the browser will not do this in some cases, such as resizing the window, changing the default font of the page, etc. For these operations, the browser will reflow immediately.
But sometimes, our script will prevent the browser from doing this, for example: if we request the following DOM values:
Because, if Our program needs these values, so the browser needs to return the latest values, and this will also flush out some style changes, resulting in frequent reflow/repaint.
Here are some Best Practices:
1) Do not modify the DOM style one by one. Instead of doing this, it is better to pre-define the css class and then modify the className of the DOM.
1
2
3
4
5
6
7
8
9
10
11
// bad
var left = 10,
top = 10;
el.style.left = left "px" ;
el.style.top = top " px" ;
// Good
el.className = " theclassname" ;
// Good
el.style.cssText = "; left: " left "px; top: " top "px;" ;
2) Modify the DOM offline. For example:
3) Do not put the attribute values of DOM nodes in a loop as variables in the loop. Otherwise this will result in a large amount of reading and writing of the attributes of this node.
4) Modify the lower-level DOM as much as possible. Of course, changing the lower-level DOM may cause a large area of reflow, but the impact may also be small.
5) Use fixed or absolute position for animated HTML elements, then modifying their CSS will not reflow.
6) Never use table layout . Because a small change may cause the entire table to be rearranged.
In this manner, the user agent can begin to lay out the table once the entire first row has been received. Cells in subsequent rows do not affect column widths. Any cell that has content that overflows uses the 'overflow ' property to determine whether to clip the overflow content.
Fixed layout, CSS 2.1 Specification
This algorithm may be inefficient since it requires the user agent to have access to all the content in the table before determining the final layout and may demand more than one pass.
Automatic layout, CSS 2.1 Specification
Sometimes, you might You will find that under IE, you don’t know what you have modified. As a result, the CPU suddenly goes up to 100%, and then it takes several seconds for repaint/reflow to be completed. This kind of thing often happens in the era of IE. Therefore, we need some tools to help us see if there is anything inappropriate in our code.
Finally, don’t forget the following articles to improve browser performance: