In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "the principle analysis of CSS". In the daily operation, I believe that many people have doubts about the principle analysis of CSS. The editor consulted all kinds of data and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts of "principle analysis of CSS". Next, please follow the editor to study!
1. Browser rendering
First of all, let's review the rendering process of the browser, as shown above:
As shown in the image above, our browser rendering process is divided into two main lines:
First, the DOM tree generated by HTML Parser
Second, the Style Rules generated by CSS Parser
After that, the DOM tree and Style Rules will generate a new object, known as the Render Tree render tree, which will be drawn on the screen with Layout to show it.
The focus of this article is on the second branch, let's explore the principle of CSS parsing.
2. Webkit CSS parser
The browser CSS module is responsible for parsing CSS scripts and calculating styles for each Element. Although the CSS module is small, it has a large amount of computation, and poor design often becomes the bottleneck of browser performance.
The CSS module has several characteristics in implementation: a large number of CSS objects (small and many particles) and frequent computation (calculation style for each Element). These characteristics determine the design and algorithm adopted by webkit in implementing the CSS engine. How to efficiently calculate the style is the focus and difficulty of the browser kernel.
Let's take a look at a picture:
Webkit uses the Flex and Bison parsing generators to automatically generate parsers from CSS syntax files.
They all parse each CSS file into stylesheet objects, each object contains CSS rules, and the CSS rule object contains selectors and declaration objects, as well as other objects that conform to CSS syntax. The following figure may be clearer:
Webkit uses automatic code generation tools to generate the corresponding code, that is, lexical analysis and parsing are generated automatically, and the CallBack function implemented in Webkit is in CSSParser.
The entrances to some of the parsing functions of CSS are also here, which will call lex, parse, and so on to generate code. On the other hand, the CallBack needed in the generated code needs to be implemented here.
For example, now let's look at the implementation of one of the callback functions, createStyleRule (), which will be called when the general rule needs to be established, as follows:
CSSRule* CSSParser::createStyleRule (CSSSelector* selector) {CSSStyleRule* rule = 0; if (selector) {rule = new CSSStyleRule (styleElement); m_parsedStyleObjects.append (rule); rule- > setSelector (sinkFloatingSelector (selector)); rule- > setDeclaration (new CSSMutableStyleDeclaration (rule, parsedProperties, numParsedProperties));} clearProperties (); return rule;}
From the implementation of this function, you can clearly see that when the parser meets a certain condition and needs to create a CSSStyleRule, the function will call this function. The function is to create a CSSStyleRule and add it to the parsed style object list m_parsedStyleObjects, where the object refers to the Rule.
In this way, after such parsing, all StyleRule in the stylesheet as input will be transformed into Webkit's internal model object CSSStyleRule object, which is stored in m_parsedStyleObjects, which is a Vector.
But what is the result of our analysis?
1. Start the above CSS parsing process by calling the parseString function of CSSStyleSheet. After parsing once, the Rule is stored in the corresponding CSSStyleSheet object.
two。 Since the current rules are still not easy to deal with, they also need to be converted to CSSRuleSet. That is, all the pure style rules are stored in the corresponding set, and the abstraction of this set is CSSRuleSet.
3.CSSRuleSet provides an addRulesFromSheet method that converts rule in CSSStyleSheet to rule in CSSRuleSet
4. Determine the style of the elements in each page based on these CSSRuleSet
3. Parsing order of CSS selector
Maybe many students know that the typesetting engine parses the CSS selector from right to left. Why?
1.HTML is parsed to generate DOM Tree (which we are familiar with); after CSS parsing, we need to analyze the parsed results together with the contents of DOM Tree to build a Render Tree, which is finally used for drawing. Elements in Render Tree (called "renderers" in WebKit and "frames" in Firefox) correspond to DOM elements, but not one to one: a DOM element may correspond to multiple renderer, for example, after text wrapping, different "lines" become different renderer of render tree. There are also DOM elements that are completely ignored by Render Tree, such as display:none elements.
two。 When establishing a Render Tree (the "Attachment" process in WebKit), the browser determines what kind of renderer is generated based on the parsing result (Style Rules) of the CSS for each element in the DOM Tree. For each DOM element, the matching selector must be found in all Style Rules and the corresponding rules must be merged. The "parsing" of the selector is actually performed here, looking for the corresponding selector from the Style Rules when traversing the DOM Tree.
3. Because the number of all style rules may be large, and most of them do not match the current DOM element (because of the large number, a rule index tree is usually created), it is extremely important to have a quick way to determine that "this selector does not match the current element."
4. If forward parsing, such as "div div p em", we must first check the entire path of the current element to html, find the top div, and then look down. If we encounter a mismatch, we must go back to the top div, and then go down to match the first div in the selector, and trace back several times to determine whether we match or not, which is inefficient.
We first have a general understanding of the above description. Let's take a look at such an example:
Span > 111span >
Span > 222span >
three hundred and thirty three
four hundred and forty four
CSS selector:
Div > div.jartto p span.yellow {color:yellow;}
For the above example, if you look it up from left to right:
1. Find all div nodes first
two。 Find all child div within the div node, and it is class = "jartto"
3. Then match p span.yellow and other situations in turn.
4. If you encounter a mismatch, you must go back to the div or p node where you started the search, and then search for the next node, repeating the process.
Such a search process is extremely inefficient for a selector that matches only a few nodes because we spend a lot of time backtracking matching nodes that do not conform to the rules.
If we change our way of thinking, we first filter out the collection that best matches the target node, and then search in this set, which greatly reduces the search space. Take a look at parsing the selector from right to left:
1. The first element found
two。 Then we judge whether the former sibling nodes in these nodes conform to the P rule, so that the elements of the set are reduced, and only if the current sub-rules are met will the previous sub-rules be matched.
The result is obvious. As we all know, an element in a DOM tree may have several child elements, and it is obvious that the performance of each of them is too poor. A child element has only one parent element, so it is very convenient to find.
Just imagine, if you read CSS rules from left to right, then most rules will not match until the end (far right), which will take time and energy, and in the end, many of them are useless; and if you use a right-to-left approach, as long as you find that the rightmost selector does not match, you can simply discard it and avoid many invalid matches.
The rules of the browser CSS matching core algorithm match nodes in a right-to-left manner. This is done to reduce the number of invalid matches, resulting in faster matching and better performance.
IV. The parsing process of CSS grammar
The parsing process of CSS stylesheet is very detailed. Here we only look at the CSS syntax interpreter. The general process is as follows:
1. Create the CSSStyleSheet object first. Stores the pointer to the CSSStyleSheet object in the CSSParser object.
2.CSSParser recognizes a simple-selector in the form of "div" or ".class". Create a CSSParserSelector object.
3.CSSParser recognizes a relational character and another simple-selecotr, then modify the previously created simple-selecotr to create a composite relational character.
4. Loop step 3 until you hit a comma or left curly braces.
5. If you encounter a comma, take out the reuse vector of CSSParser, then pop the CSSParserSelector object at the end of the stack into Vecotr, and finally jump to step 2. If you encounter the left curly braces, jump to step 6.
6. Recognize the attribute name and press the hash value of the attribute name into the interpreter stack.
7. Recognize the property value, create a CSSParserValue object, and store the CSSParserValue object on the interpreter stack.
8. The property name and value are popped off the stack to create a CSSProperty object. And store the CSSProperty object in the CSSParser member variable m_parsedProperties.
9. If you recognize the attribute name, go to step 6. If you recognize the right curly braces, go to step 10.
10. Pop reuse vector off the stack and create a CSSStyleRule object. The selector of the CSSStyleRule object is reuse vector, and the style value is the member variable m_parsedProperties of CSSParser.
11. Add CSSStyleRule to the CSSStyleSheet.
twelve。 Clear the results of the CSSParser internal cache.
13. If there is no content, then it is over. Otherwise, jump value step 2.
5. How to analyze the inline style?
From what we've learned above, we know that when CSS Parser finishes parsing the CSS script, it generates a CSSStyleSheetList, which is saved on the Document object. For faster calculation styles, these CSSStyleSheetList must be reorganized.
The calculation style is to find all the property-value pairs that match the corresponding elements from the CSSStyleSheetList. The match is verified by CSSSelector and the cascading rules need to be met.
Organize all the property in declaration into a large array. Each item in the array records the value of the selector,property of this property, the weight (cascading rule).
It may be similar to the following performance:
P > a {color: red; background-color:black;} a {color: yellow} div {margin: 1px;}
The reorganized array data is (weight I just represent the relative size between them, not the actual value. )
All right, here we are, let's solve the above problems:
First of all, make it clear that the introverted style is only one of the three ways to load CSS.
Secondly, browser parsing is divided into two branches, HTML Parser and CSS Parser, each of which does its own job and does its part.
Finally, the Style rule generated by different CSS loading methods uses weights to determine who overrides who.
It is not difficult to understand that for browsers, the only difference between inline styles and other loading styles is that they have different weights.
For more information, please read Webkit CSS engine Analysis
6. What is computedStyle?
When you get here, you think it's over? Too young too simple, sometimes naive!
Browsers also have a great strategy. Under certain circumstances, browsers will share computedStyle, and there are many tags that can be shared on web pages, so it can greatly improve the efficiency of execution! If it can be shared, there is no need to implement the matching algorithm, and the execution efficiency is naturally very high.
That is, if the computedStyle of two or more element can be confirmed to be equal without calculation, then the elements of these computedStyle equality will only calculate the style once, and the rest will only share the computedStyle.
So what are the rules that share computedStyle?
The shared element cannot have an id attribute and there is a StyleRule of the id in the CSS. Even if the StyleRule does not match the Element.
TagName and class properties must be the same
MappedAttribute must be equal
Cannot use sibling selector, such as first-child,: last-selector, + selector
Cannot have style attribute. Even if the style attribute is equal, they will not share it.
Span > p style= "color:red" > paragraph2span > p > span > p style= "color:red" > paragraph3span > p > at this point, the study of "interpretation of the principle of CSS" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.