Front-end knowledge Body (1) – Browser

The original


It has been almost three years since I started my study, and I always feel that my knowledge of this industry is a little messy. Therefore, I hope to make a connection through this opportunity to sort out and form my own knowledge system. Hope to help other front-end ER.

Browser Composition


  • Interface controls– Except for the main browser window, other parts, including the address bar, forward and back buttons, belong to the browser interface control
  • Browser engine– Pass the user interface to the rendering engine
  • Rendering engine– Responsible for parsing CSS and HTLML pages displayed in the browser window
  • Network request– User network requests, such as HTTP requests.
  • The UI backend– Draw basic components such as combo boxes and Windows.
  • JS parser– Used to parse executing JavaScript code.
  • Data is stored– Persistence layers, such as sessionStorage, Cookies, localStorage, and browser built-in databases.

Note: Unlike other browsers, Chrome uses multiple rendering engine instances, one per Tab page, meaning that each Tab is a separate process.

Processes and threads in the browser


  1. GUI rendering thread
  2. JavaScript engine threads
  3. Timer trigger thread
  4. Event trigger thread
  5. Asynchronous HTTP request threads

The browser threads above are all part of what we need to know as a front-end.

The process of browser rendering


The rendering process has four main steps:

  1. Parsing HTML to Generate A DOM Tree – The rendering engine first parses the HTML document to generate a DOM tree
  2. Whether inline, inline or embedded CSS styles are parsed to generate a CSSOM Tree, which is merged with the DOM Tree to generate another Render Tree.
  3. Layout the Render Tree – Determines where each node of the Render tree is displayed on the page
  4. Draw the Render tree – Walk through the Render tree and draw the corresponding nodes using the UI back-end layer

The above steps are a gradual process, in order to improve the user experience, the rendering engine tries to render the results to the end user as quickly as possible. It does not wait until all the HTML has been parsed before creating and laying out the render tree. It will fetch the contents of the document from the network layer while showing the partial contents that have been received.

1. Parse HTML to generate a DOM tree

DOM tree construction is a process of deep traversal: the next sibling node of the current node will be constructed only after all the child nodes of the current node have been constructed. The DOM tree building process can be blocked by the loading execution of CSS and JS.

About blocking CSS loads:

<! DOCTYPE HTML > < HTML lang='en'> <head> <title> CSS block </title> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1'> <style> h1 { color: red ! important } </style> <script> function h () { console.log(document.querySelectorAll('h1')) } setTimeout(h, 0) < / script > < link href = "https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel = "stylesheet" > < / head > <body> <h1> This is in red </h1> </body> </ HTML >Copy the code

The console prints the DOM element H1 before the CSS is loaded, but the page is still blank. The page does not appear until the CSS is loaded, indicating that the CSS loading does not block parsing of the DOM tree, but does block rendering of the DOM tree.

<head>
  <link rel='stylesheet' href='/main.css' />
  <script>
    console.log('I did it.')
  </script>
</head>
Copy the code

In the case of the above code, the console does not print any information when the CSS loading is not complete. The output information will be displayed after the CSS loading is complete, indicating that the CSS loading will block the execution of subsequent JS statements. Through the above code, we can draw the following conclusions:

  1. CSS loading does not block parsing of the DOM tree
  2. CSS loading blocks DOM tree rendering
  3. CSS loading blocks the execution of subsequent JS statements

In the ideal situation without JS, HTML and CSS will be parsed in parallel, generating DOM and CSSOM respectively, and then merged into Render Tree, Rendering Pipeline; But with JS, CSS loading blocks subsequent JS statements, and (synchronous) JS script execution blocks subsequent DOM parsing (so CSS is usually put at the head and JS at the end of the body).

JS load blocking:

  1. The external script is encountered before parsing the DOM tree. If there is no async, defer attribute, the document loading will be blocked and parsing will continue after the script is loaded. If the script has the async, defer attribute, the browser will create another thread to load the script, and for the async attribute, the script will be executed immediately after loading.
  2. After DOM parsing, document.readyState = ‘interactive’, the script for the defer property starts executing sequentially, and then the DOMContentLoaded event is triggered, marking the transition from synchronous script execution to event-driven execution.
  3. The async property script will be executed when it is loaded, either during the HTML parsing phase or after DOMContentLoaded. The async property script will block the load event. When all the async scripts have been executed and img and other resources have been loaded, Document. readyState = ‘complete’, the window object will fire the load event.

2. Generate Render tree

The CSS Object Model (CSSOM) Tree will be generated when the DOM Tree is generated, and then the Render Tree will be constructed according to the CSSOM and DOM Tree. The Render Tree contains rectangles with color, size and other display attributes, and the order of these rectangles is basically the same as the display order.

3. Layout and drawing

With the renderer’s style rules established above, it’s time for the important layout of the display elements. When the Renderer is constructed and added to the Render tree, it has no position or size information. The process of determining this information is followed by the layout.

4. Reflow and redraw

Reflow: When the browser finds that something has changed that affects the layout and needs to go back and rerender. Reflow computs the geometry and position of all nodes recursively from the root frame < HTML >. Reflow is almost inevitable. Some of the current interface effects, such as tree directories collapsing and expanding (essentially showing and hiding elements), will cause reflow in the browser. Mouse slide, click… As long as these actions cause changes in the space area, positioning, margins and other attributes of some elements on the page, they will cause it to be re-rendered in, around, and even the entire page. It is often impossible to predict which parts of the code the browser will reflow, and they all affect each other. Repaint: Changing an element’s background color, text color, border color, etc., without affecting its surrounding or internal layout, a portion of the screen is repainted, but the element’s geometry remains the same.

Triggering backflow always triggers redraw, but redraw does not necessarily trigger backflow

Performance impact

  • The cost of backflow is much higher
  • Modern browsers are optimized for frequent backflow and redraw operations by putting all backflow or redraw operations into a queue and working together to avoid multiple backflow and redraw operations