Browser rendering process

Browser, DOM, JS, HTML

Several concepts

  • DOM Tree: The browser parses HTML pages using the DOM and generates themHTML treeTree-like data structures and corresponding access methods
  • CSS Rule Tree: The browser parses the CSS through the DOM and generates itCSS Rule TreeTree-like data structures
  • Render Tree: A Tree generated by merging visual nodes (DOM) and CSS styles (CSSOM)
  • Layout: aRender TreeBrowsers already know which nodes are in a web page, their CSS definitions, and their dependencies to figure out where each node is on the screen
  • Painting: Work out the rules and use the graphics card to paint the content on the screen
  • Reflow: whenRender TreeIn part or all nodes, due to the size, layout, hiding, etc., need to be rebuilt, calculate their exact position and size in the device viewport (viewport), the browser rendering process is called backflow
  • Repaint: When elements in a page style (e.g.color,background-colorWhen the surrounding or internal layout (size, size, etc.) is not affected, the browser will assign the new style to the element and redraw it, a process called redraw

Pay attention to

Elements with display none do not need to be rendered on the page, and the render tree build does not include these nodes; But elements whose visibility is hidden will be in the render tree. Because display none will be out of the document flow, visibility will be hidden, although you can’t see it, but like transparency is 0, it will still be in the document flow, there will be a rendering process.

Display: None will trigger reflow, while visibility: Hidden will only trigger repaint because no position changes have been detected.

Rendering process

Webkit’s main flowchart

Rendering process

  1. The browser parses the HTML into a DOM tree, which is built by deep traversal: all children of the current node are built before the next sibling of the current node is built.
  2. Parse the CSS into CSS Rule Tree.
  3. Construct Rendering Tree according to DOM Tree and CSSOM. Note: Rendering Tree is not the same as DOM Tree, because something like Header or display: None doesn’t need to be in the Rendering Tree.
  4. With Render Tree, browsers already know what nodes are in a web page, their CSS definitions, and their dependencies. The next step is called Layout, which, as the name suggests, calculates the position of each node on the screen.
  5. The next step is to draw, which is to traverse the Render tree and draw each node using the UI back-end layer.

Pay attention to

The rendering process is done step by step, and for a better user experience, the rendering engine will render the content to the screen as early as possible, rather than wait until all the HTML has been parsed before building and laying out the Render tree. It parses part of the content and displays part of the content, while probably downloading the rest of the content over the network.

View your browser’s rendering process

Reflux + redraw

Backflow will certainly cause redrawing, redrawing will not necessarily cause backflow;

Backflow costs more than repainting;

backflow

Operations that cause backflow:

  • Page rendered for the first time.
  • The browser window size changed. Procedure
  • The size or position of the element changed.
  • Element content changes (the number of words or image size changes).
  • Element font size changes.
  • Add or removevisibletheDOMElements.
  • The activationCSSPseudo-classes (eg::hover).
  • Query some properties or call some methods.

Some common properties and methods that cause backflow.

  • clientWidth,clientHeight,clientTop,clientLeft
  • offsetWidth,offsetHeight,offsetTop,offsetLeft
  • scrollWidth,scrollHeight,scrollTop,scrollLeft
  • scrollIntoView(),scrollIntoViewIfNeeded()
  • getComputedStyle()
  • getBoundingClientRect()
  • scrollTo()

redraw

Some attributes of the node change, but does not affect the layout, just need to recalculate the node in the screen and render the process

CSS that is easy to redraw

  • color
  • Border style border-style
  • The rounded border – the radius
  • Text decoration text-decoration
  • Shadow box – shadow
  • Outline the outline
  • Background background

Pay attention to

In some cases, such as modifying the elements of style, the browser will not immediately reflow or repaint once, the browser will maintain a queue, put all cause re-flow and re-paint operation in the queue, if the number of tasks in the queue or interval reaches a certain critical value, the browser will turn to perform, a batch, The queue is emptied so that multiple reflows and redraws become one, also known as asynchronous reflow or incremental asynchronous reflow.

However, in some cases, the queue is forced to empty, i.e. forced backflow, such as resize window, changing the default font of the page, etc.

When the following properties or methods are accessed, the browser immediately clears the queue and reflow immediately:

  • clientWidth,clientHeight,clientTop,clientLeft
  • offsetWidth,offsetHeight,offsetTop,offsetLeft
  • scrollWidth,scrollHeight,scrollTop,scrollLeft
  • scrollIntoView(),scrollIntoViewIfNeeded()
  • getComputedStyle()
  • getBoundingClientRect()
  • scrollTo()

Optimized reflux reduction

There is no change in orientation, only a fading

Try to set the element to visibility because display: None causes backflow and visibility only causes redraw.

Avoid the use oftablelayout

Try not to use a table layout. If there is no fixed width and the width of a table column is determined by the widest column, it is likely that the last row will be wider than the previous column width, causing an overall backflow and causing the table to need multiple computations to determine the attributes of its nodes in the render tree, often taking three times as long as the equivalent element.

For complex animation effects, use absolute positioning to keep them out of the document flow

For complex animation effects, which often cause backflow redrawing, try to set elements to absolute or fixed, so that they are removed from the document stream. When operating on the location attribute of an element, only this element will be backflowed, otherwise it is easy to cause frequent backflows of the parent element and subsequent elements.

Merge style changes

Reduce the amount of backflow. If multiple CSS properties are being manipulated on a node, and each one causes backflow, it is better to rewrite the style property at once, or define the style list as class and change the class property at once (rather than using JS to change each style individually).

Batch operation DOM

Special handling is required to reduce backflow when multiple operations are performed on the DOM. Multiple operations on an element after leaving the standard flow do not trigger backflow. When the operation is complete, the element is put back into the standard stream.

There are three types of operations that deviate from the standard flow:

  1. Hide elements (display: None, only causes two reflow and redraw)
  2. Using document fragments (createDocumentFragment: Create a virtual documentFragment node)
  3. Copy the node

Example: The following multiple operations on the DOM node trigger backflow each time

Var data = [{id: 1, name: "1" goods,}, {id: 2, name: "1" goods,}, {id: 3, name: "1" goods,}, {id: 4, name: "1" goods,}, / / assumptions behind many]; var oUl = document.querySelector("ul"); for(var i=0; i<data.length; i++){ var oLi = document.createElement("li"); oLi.innerText = data[i].name; oUl.appendChild(oLi); }Copy the code

In this way, each operation to add a LI to ul triggers backflow each time.

Method 1: Hide the UL, add a node to the UL, and then display the UL

oUl.style.display = 'none'; for(var i=0; i<data.length; i++){ var oLi = document.createElement("li"); oLi.innerText = data[i].name; oUl.appendChild(oLi); } oUl.style.display = 'block';Copy the code

At this point, backflow is triggered twice when ul is hidden and ul is shown, and no backflow is triggered when each LI is added to ul.

Method 2: Create a document shard, put all li in the document shard first, and then put the document shard in ul

var fragment = document.createDocumentFragment(); for(var i=0; i<data.length; i++){ var oLi = document.createElement("li"); oLi.innerText = data[i].name; fragment.appendChild(oLi); } oUl.appendChild(fragment);Copy the code

DocumentFragment represents a minimal document object that has no parent file. The biggest difference from Document is that DocumentFragment is not part of the real DOM tree, and changes to it do not trigger the DOM tree (re-rendering) or cause performance issues.

The use of the document. CreateDocumentFragment method or constructor to create an empty DocumentFragment.

detailed

Method 3: Make a copy of ul, put all li in the copy, and replace ul with a copy (deep copy) when all li are in the copy.

var newUL = oUl.cloneNode(true); for(var i=0; i<data.length; i++){ var oLi = document.createElement("li"); oLi.innerText = data[i].name; newUL.appendChild(oLi); } oUl.parentElement.replaceChild(newUl, oUl);Copy the code

Pay attention to

CloneNode () stands for shallow copy – the element in the tag, the event is not copied. CloneNode (true) stands for deep copy – copying exactly what’s in the real node

Avoid triggering layouts more than once

Retrieves an element’s scrollTop, scrollLeft, scrollWidth, offsetTop, offsetLeft, offsetWidth, offsetHeight and other attributes. So if you’re going to do it multiple times, you might want to cache it.

Back to the top operation as follows:

goBack.onclick = function(){ setInterval(function(){ var t = document.documentElement.scrollTop || document.body.scrollTop; t += 10; document.documentElement.scrollTop = document.body.scrollTop = t; }}, 20)Copy the code

Every 20 milliseconds, the scrolling distance is reacquired, and each time a backflow is triggered. The code is optimized as follows:

goBack.onclick = function(){ var t = document.documentElement.scrollTop || document.body.scrollTop; setInterval(function(){ t += 10; document.documentElement.scrollTop = document.body.scrollTop = t; }}, 20)Copy the code

Get it only once, increasing the number each time to avoid getting the scrolling distance each time.