Browser rendering mechanism
Browser process
- Browser process: mainly responsible for interface display, user interaction, sub-process management, and storage.
- Render process: The core task is to turn HTML, CSS, and JavaScript into web pages that users can interact with. Both the typography engine Blink and JavaScript engine V8 run in this process. By default, Chrome creates a rendering process for each Tab Tab. For security reasons, renderers are run in sandbox mode.
- GPU process: Actually, Chrome didn’t have a GPU process when it was first released. The original intention of using GPU was to achieve 3D CSS effect, but later the UI interface of web page and Chrome were drawn on GPU, which made GPU become a common requirement of browser. Finally, Chrome has introduced GPU processes on top of its multi-process architecture.
- Web process: responsible for loading web resources on a page. It used to run as a module in the browser process until recently, when it became a separate process.
- Plug-in process: the plug-in process is mainly responsible for running plug-ins. Plug-ins are prone to crash. Therefore, the plug-in process is isolated to ensure that the plug-in process crash does not affect the browser and page.
The typography engine is what we call the rendering engine, or what we call the browser kernel.
Common browser cores: Trident => IE, Gecko => Firefox, Webkit => Safari/Chrome, Presto => Opera
“What happens in the browser between entering the URL and presenting the page?”
1. Enter the URL
The browser determines whether the input content is a URL. If not, the browser uses the default search engine to synthesize a new URL with search keywords. If the input content complies with URL rules, the browser adds protocols to synthesize a complete URL.
2. The URL request
-
The browser process sends the URL request through interprocess communication (IPC) to the network process, which initiates the actual URL request.
-
The network process checks whether the local cache has cached the resource. If there is a cached resource, it directly returns the resource to the browser process. If there is no cached resource, it enters the network request process.
-
The first step before the request is DNS resolution to obtain the server IP address of the requested domain name. If the requested protocol is HTTPS, a TLS connection needs to be established.
-
Establish a TCP connection with the server using an IP address.
-
Construct the request line, request information, etc., and attach data such as cookies related to the domain name to the request header, and then send the constructed request information to the server.
-
After receiving the request information, the server generates response data (including response line, response header, and response body) based on the request information and sends it to the network process.
-
After receiving the response, the network process parses the contents of the response header.
-
If the returned status code is 301 or 302, read the redirected address from the Location field in the response header and initiate a new HTTP or HTTPS request.
-
If the response line is 200, determine the Type of the response body data returned by the server based on the content-type. If the content-Type field in the response header is text/ HTML, the data returned by the server is IN HTML format.
3. Prepare the rendering process
Same site: pages with the same root domain name (for example, geekbang.org) and protocol (for example, https:// or http://).
Chrome assigns a rendering process to each page by default, but if a new page is opened from one page and the new page belongs to the same site as the current page, the new page will reuse the parent page’s rendering process.
4. Submit documents (i.e. response body data)
-
The browser process sends a “submit request” message to the renderer process. After receiving the “submit document” message, the renderer process establishes a “pipeline” to transmit data with the network process.
-
After the document data transfer is complete, the renderer process returns a “confirm submit” message to the browser process.
-
After receiving the “confirm submission” message, the browser process updates the browser interface status, including the security status, the URL of the address bar, the historical status of forward and backward, and the Web page.
5. Rendering process
- Build a DOM tree
The browser reads the raw HTML bytes from the response body and specifies the encoding (such as UTF-8) to convert the string into a Token, which identifies information such as “start tag,” “end tag,” or “text.” Such as “StartTag:head”, “EndTag:title”, “sometext”, then generate node objects by Token, and finally build a DOM tree.
In fact, in the process of DOM construction, instead of generating node objects after all tokens are converted, the node objects are generated by consuming tokens while generating tokens. In other words, as soon as each Token is generated, the Token is consumed to create a node object. Note: Tokens with an end tag identifier do not create node objects.
- Build CSSOM tree
The process of building CSSOM is similar to the process of building the DOM.
There are three main sources of CSS styles:
- External CSS files referenced by link
<style>
CSS inside the tag- Element’s style property is embedded with CSS
During this process, the browser determines what the style of each node is, and this process can be very resource-intensive. Because styles can be set to a node or inherited. In this process, the browser recurses the CSSOM tree to determine the specific element style.
- Building the Render tree (Layout tree)
Iterate through all the visible nodes in the DOM tree and add them to the render tree. Invisible nodes are ignored, such as the entire content below the head tag, elements with style attributes including dispaly: None, and so on.
Computes the coordinate positions of nodes in the render tree.
- Building a hierarchical tree
The rendering engine generates layers for specific nodes and a tree of layers for each node.
This involves cascading context, see this article: cascading context, cascading hierarchy, cascading order (see this if you can’t open it).
- Production drawing list
Divide the drawing of each layer into a number of small drawing instructions, and then put these instructions in order to form a drawing list.
A draw list is simply a list of draw orders and draw instructions that are actually done by the compositing thread in the rendering engine.
So this step also commits the draw list to the composition thread.
- rasterize
The compositing thread will divide the layer into tiles and generate bitmaps in preference to tiles near the viewport. The actual bitmap generation is performed by rasterization. Rasterization refers to the transformation of a map block into a bitmap. The graph block is the smallest unit for rasterization. The renderer process maintains a rasterized thread pool, where all rasterization of blocks is performed. Generally, GPU is used to accelerate the generation of bitmaps during rasterization. The process of using GPU to generate bitmaps is called fast rasterization, or GPU rasterization. The generated bitmaps are stored in GPU memory.
- synthetic
After all the blocks are rasterized, the composite thread sends the command DrawQuad to the browser process.
- According to
The browser process has a component called viz that receives DrawQuad commands from the compositing thread, draws its page contents into memory, and displays them on the screen.
Understand reflux (rearrangement), redraw, composition
Reflux (rearrangement)
When some or all of the elements in the render tree change in a way that causes the geometry of the elements, such as changing the width or height of the elements, the browser triggers a rearrangement, a process called backflow or rearrangement.
Operations that cause backflow:
- Page first render
- The browser window size changed. Procedure
- Changes in element size or position (margins, padding, borders, width, and height)
- Element content changes (number of words or image size, etc.)
- Element font size changes
- Add or remove visible DOM elements
- Calculate the offsetWidth and offsetHeight properties
- Set/query certain properties, call certain methods
Common properties and methods that cause backflow:
- Width, height, margin, padding, border
- Display, position, overflow
- ClientWidth, clientHeight, clientTop, clientLeft
- OffsetWidth, offsetHeight, offsetTop, offsetLeft
- ScrollWidth, scrollHeight, scrollTop, scrollLeft
- ScrollIntoView (), scrollIntoViewIfNeeded ()
- getComputedStyle()
- getBoundingClientRect()
- scrollTo()
redraw
When a change in the style of an element on a page does not affect its position in the document flow, such as changing the background color of an element, the layout is not reexecuted because there is no change in geometry. Instead, the browser assigns the new style to the element and redraws it, a process called redrawing.
Redraw eliminates layout and layering, so it is more efficient than rearrange.
Common properties and methods that cause redrawing:
- Color, text-decoration, visibility
- Background, background-image, background-position, background-repeat, background-size
- Outline, outline-color, outline-style, outline-radius, outline-width
- Border – style, box – shadow
synthetic
Changing a property that does not lay out or draw, such as using CSS’s Transform to animate, the rendering engine skips layout and draw and only performs subsequent compositing, a process we call compositing.
conclusion
Backflow will certainly cause repainting, and repainting will not necessarily cause backflow.
Reduce backflow and redraw:
- Use transform instead of top
- Replace display: None with visibility
- Do not put node property values in a loop as variables in the loop
for(let i = 0; i < 1000; i++) {
console.log(document.querySelector('.test').style.offsetTop)// Retrieving offsetTop causes backflow
}
Copy the code
- Avoid using a table layout
The browser maintains a queue that queues all operations that cause backflow and redraw, and if the number of tasks or time intervals in the queue reaches a threshold, the browser emptying the queue and doing a batch, thereby turning multiple backflow and redraw into one.
The browser clears the queue immediately when you access the following properties or methods:
- ClientWidth, clientHeight, clientTop, clientLeft
- OffsetWidth, offsetHeight, offsetTop, offsetLeft
- ScrollWidth, scrollHeight, scrollTop, scrollLeft
- Width, height,
- getComputedStyle()
- getBoundingClientRect()
Because there may be operations in the queue that affect the return value of these properties or methods, even if the information you want is not related to the change caused by the operation in the queue, the browser will force the queue to empty to make sure you get the most accurate value.
other
How to deal with JS files encountered in rendering process
Loading, parsing, and executing JavaScript blocks DOM building, so to speed up first-screen rendering, it is recommended to place the Script tag at the bottom of the body tag, or alternatively, add defer or async properties to the script tag.
Because JavaScript can change both the DOM and CSS, incomplete CSSOM cannot be used. When executing the JS, you must get the complete CSSOM. This leads to a phenomenon that if the browser has not finished downloading and building the CSSOM, If we want to run the JS script at this point, the browser must first download and build the CSSOM, then execute the JS script, and then continue building the DOM.
About defer and Async:
<script src="index.js"></script>
Without defer or Async, the browser loads and executes the specified script immediately, meaning it reads and executes document elements without waiting for them to be loaded later.<script async src="index.js"></script>
The async property represents asynchronous execution of the introduced JavaScript, which differs from defer in that it starts execution if it is already loaded.<script defer src="index.js"></script>
The defer attribute indicates that js execution is delayed, and the JS loading of defer is set to not block the DOM build, that is, the HTML does not stop parsing when JS is loaded. The two processes are parallel, and the script loaded by defer-script is executed only after both are complete.- When loading multiple JS scripts, Async loads sequentially, while defer loads sequentially.
Why is DOM manipulation slow
Because DOM belongs to the rendering engine, JS executes in the JS engine. Manipulating the DOM through JS involves communication between two threads, and manipulating the DOM can also lead to redraw backflow.
What are the common bad phenomena when rendering pages
Due to the different rendering mechanisms of browsers, there are two common bad phenomena that occur when rendering pages — white screen and FOUS (unstyled content flickering).
FOUC: Due to browser rendering mechanisms (such as Firefox), rendering HTML before CSS loads results in unstyled content being displayed and then styles suddenly appearing.
White screen: Some browser rendering mechanisms (such as Chrome) require the DOM tree and CSSOM tree to be constructed and rendered after completion. If the CSS part is placed at the end of the HTML, the browser delays rendering because the CSS has not been loaded, resulting in a white screen. Alternatively, if the JS file is placed in the header, the script will block the presentation of the following content, and the script will block the download of the following components, resulting in a blank screen.
reference
How browsers work and practice – Geek Time
Browser kernel parsing and comparison
Simple browser rendering principles
Reflow & Repaint for browsers