preface

The introduction in Three Things gives you a vague idea of what a browser is made of:

  1. What is a browser?
  2. Browser (Chromium) basic architecture
  3. Major browser components
  4. What is the browser kernel?
  5. JavaScript (js) engine
  6. Rendering engine

Today, I will do WebKit to study and discuss.

First of all, as a sequential introduction. I should go into the details of what it takes to implement a browser (just to show you what the Chromium implementation includes). But consider the introduction at the front end. Do simple enumerations without discussing them in detail; You can study by yourself if you are interested.

Second, I should focus on the JS engine (related to V8 event-loop) to the extent that you are familiar with it; However, in this section, I want to introduce and discuss the rendering engine (WebKit) first. For no other reason than I like to play. Because I wrote this series for a front-end audience, I use JavaScript to implement the parts that require code intervention.

Rendering engine

Get used to building pictures, don’t worry about the ugly details.

The figure above gives an overview of the rendering engine’s internal parsing process:

  1. When a page is visited, a network request is made to retrieve the content of the page; If the cache is hit, it is read directly from memory.
  2. HTMLParser parses HTML and blocks it with specific tags. Can parse into CSS DOM JS several modules.
  3. CSSParser does CSS parsing as well.
  4. DOMParser parses DOM structures. (Build process is found to be JS part of the execution 5, if the resource is asynchronous request. Does not hinder parsing).
  5. The JavaScript parts are thrown to the JS engine for parsing. (Manipulation of the DOM/CSS section will affect the previous parsing and hinder parsing).
  6. Build RenderTree from the above analysis.
  7. After parsing, layout and drawing are done through renderTree.
  8. The final image is displayed on the screen.

Here is a discussion of the above mentioned part


The Parser parsed

Is the word Parser too much? We got a message parsing is a very important part of the rendering engine, so we need to introduce parsing first.

Parsing a document means turning the document into a meaningful structure, that is, one that the code can understand and use. The result of parsing is usually a tree of nodes representing the structure of the document, called a parse tree or syntax tree.

Parsing is based on the syntax rules that the document follows (the language or format in which the document is written). For example, HTML parsing is done on the HTML4/5 specification. All parsable formats must correspond to a definite grammar (consisting of vocabulary and grammar rules).

The parsing process is usually divided into two sub-processes: lexical analysis and grammatical analysis. Lexical analysis is the process of splitting input into a large number of tags. Parsing is the process of applying the grammatical rules of a language (what the language actually does).

HTMLParser

The task of an HTML parser is to parse HTML tags into parse trees.

HTML syntax Definition: The vocabulary and syntax of HTML are defined in a specification created by the W3C organization.

The output “parse tree” of a DOM parser is a tree structure composed of DOM elements and attribute nodes. DOM is short for Document Object Model. It is an object representation of an HTML document and an interface between external content (such as JavaScript) and HTML elements. The root node of the parse tree is the Document object.

The first thing to understand about DOM parsing code is that the parsing process must be iterative:

Tag < > / / analysis and properties of the regular expression var startTag = / ^ < ([9 - A - Za - z0 - _] +) ((? :\s+[\w-]+(? :\s*=\s*(? : (? :] "[^" * ") | (? :'[^']*')|[^>\s]+))?) *)\s*(\/?) >/, endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/, attr = /([-A-Za-z0-9_]+)(? :\s*=\s*(? : (? : "((? : \ \ [^ | | "]) *) ") (? : '((? :\\.|[^'])*)')|([^>\s]+)))? /g; Function ParserHTML(HTML){// accept HTML while(HTML){// match annotation if(html.indexof ("<! - ") = = 0) {/ /} / / match began to label the if (HTML. IndexOf (" < ") = = 0) {match = HTML. Match (startTag); if (match) { html = html.substring(match[0].length); Matching interception / / / / continued iteration}} the if (HTML. IndexOf (" < / ") = = 0) {/ / matching end tag}}} {/ / output signal structure element: ", "parentNode: {}, childrenNode: {}, content:"", .... } // I can't find the one I wrote before. Feel free to communicate any questions this sample re is available.Copy the code

CSSParser

CSS parses context-free syntax unlike HTML; Parsing can be done through a number of parsers. Lexical syntax (vocabulary) is defined with regular expressions for individual tags:

  • comment/ * [^]* + ([^ /] [^]* +)/
  • num[0-9] + | [0-9] * “, “[0-9] +
  • nonascii[\ 200-377 \]
  • nmstart [_a-z]|{nonascii}|{escape}
  • nmchar [_a-z0-9-]|{nonascii}|{escape}
  • name {nmchar}+
  • ident {nmstart}{nmchar}*

Automatically creating a parser from a CSS syntax file creates a bottom-up shift reduction parser. The CSS file is parsed into StyleSheet objects, and each object contains the CSS rules. CSS rule objects contain selectors and declaration objects, as well as other objects corresponding to the CSS syntax. As follows:

RenderTree

Along with the DOM tree, the browser builds another tree structure: the render tree. This is a tree of visual elements in the order in which they are displayed, and a visual representation of the document. What it does is it lets you draw the content in the right order.

The WebKits RenderObject class is the base class for all render trees and is defined as follows:

class RenderObject{ virtual void layout(); // Layout virtual void paint(PaintInfo); // Draw virtual void rect repaintRect(); // Rect Node* Node; // DOM node RenderStyle* style; Render style RenderLayer* containgLayer; //render layer }Copy the code
The relationship between the render tree and DOM tree

The render tree corresponds to the DOM element, but not one to one. Non-visual DOM elements, such as the “head” element, are not inserted into the render tree. If the element has a display attribute value of “None”, it will not be displayed in the render tree either (although elements with a visibility attribute value of “hidden” will still be displayed).

The example of multiple render trees is invalid HTML. According to the CSS specification, an inline element can contain either a block element or an inline element. If mixed content occurs, an anonymous block rendering tree should be created to wrap inline elements.

There are some render objects that correspond to DOM nodes, but are located differently in the tree than DOM nodes. This is the case for floating and absolute located elements, which are placed outside the normal flow, elsewhere in the tree, and map to the real frame, while placeholder frames are placed in place.

layout

When the rendered tree is created, it does not contain location and size information. The process of calculating these values is called layout or rearrangement.

HTML uses a flow-based layout model, which means that in most cases the geometry information can be computed in a single walk. Elements at the back of the stream typically do not affect the geometric characteristics of those at the front, so the layout can traverse the document from left to right and top to bottom. There are exceptions, such as HTML tables that require more than one walk (3.5).

The coordinate system is established relative to the root frame, using the upper and left coordinates.

Layout is a recursive process. It starts with the root render tree (which corresponds to the elements of the HTML document) and then recursively traverses some or all of the framework hierarchy, calculating the geometric information for each render tree that needs to be computed.

The position of the root render tree is 0,0 in the upper-left corner, and (in accordance with the canvas2D coordinates) its size is the viewport (that is, the visible area of the browser window). All render trees have a layout or reflow method, and each render tree will call the layout method of its descendants to be laid out.

draw

During the draw phase, the system traverses the rendered tree and calls the render tree’s paint method to display the contents of the rendered tree on the screen. Drawing is done using the user interface base component.

The order in which the elements are drawn is simply the order in which they enter the stack style context; From back to front. The stack order of the block render tree is as follows:

  1. The background color
  2. The background image
  3. A border
  4. Their offspring
  5. outline

Drawing implementation can refer to Canvas (Canvas must learn ah always pay attention to some cutting-edge actions), understand the basic drawing method and process. For example, draw line(requires coordinate base primitive structure, etc.):

The last

Distance from the last article’s life diary: 20210521 that day it is still happy (circle of friends is still not active). 20210522 I’m not happy. 20210523 that is, today is generally ok and did not learn. (Work and rest haha)

Then because recently someone always wechat I programming paradigm in the end which is a good choice? What programming paradigm am I using more now? What about the difficulty of writing your own code and maintaining it? . Before the next JS engine, I will make a brief introduction of programming paradigm for your reference (expected tomorrow).

Come on! Have a question please feel free to leave a message, see will reply

Relevant reference

  1. Syntax and syntax of CSS
  2. Processing model
  3. WebCore Rendering