preface

Backflow and redraw are very important for the front end, we need to know not only what backflow and redraw are, but also how to optimize. A page from loading to completion, the first is to build a DOM tree, and then according to the geometric properties of the DOM node to form the render tree (render tree), when the rendering tree is completed, the page begins to layout according to the DOM tree, the render tree also according to the set style corresponding to render these nodes. In this process, backflow is associated with DOM trees, render trees, and redraw is associated with render trees.

If this article helps you, ❤️ follow + like ❤️ to encourage the author, the article public account first, followThe front nine southGet the latest articles for the first time

Page rendering process

  • Parsing HTML to build a DOM Tree
  • Parse the CSS to build the CSSOM Tree
  • Build the Render Tree, 🌲 contains only the nodes needed to Render a web page

To build the render tree, the browser basically does the following:

  1. Each visible node is traversed starting at the root of the DOM tree.
    • Some nodes are not visible (such as script tags, meta tags, etc.) and are ignored because they do not show up in the render output.
    • Some nodes are hidden by CSS (such as display: None) and are therefore ignored in the rendering tree.
  2. For each visible node, find suitable CSSOM rules for it and apply them.
  3. Emit visible nodes, together with their contents and computed styles.

Note that visibility: hidden is different from display: None. The former hides the element, but the element still occupies layout space (rendering it as an empty box), while the latter (display: None) completely removes the element from the rendering tree, and the element is neither visible nor part of the layout.

The final render output contains all the visible content on the screen and its style information at the same time. With the render tree, we are ready to enter the “Layout” phase.

  • The layout calculates the exact position and size of each DOM object
  • Render (draw, compose), rendering pixels onto the screen using the final render tree

For details on the page rendering process, see my previous post on page loading in great detail, where we focus on redrawing and reflow.

What are Reflow and Repaint?

Reflow

When part (or all) of the Render tree needs to be rebuilt due to changes in element size, layout, hiding, etc. This is called reflow. Each page needs to backflow at least once, even when the page is first loaded, which is bound to happen because the Render Tree is being built. During backflow, the browser invalidates the affected part of the render tree and reconstructs that part of the render tree. When backflow is complete, the browser redraws the affected part to the screen, a process called redraw.

Simply put, backflow is calculating the exact position and size of the element within the device and redrawing it

Backflow costs more than repainting. And backflow will inevitably cause redrawing, but redrawing will not necessarily cause backflow.

Repaint

When some elements in the render tree need to be updated, but these style attributes only change the appearance and style of elements, and do not affect the layout, such as background-color. This is called repaint.

In simple terms, redraw is the conversion of rendered tree nodes to actual pixels on the screen, and does not involve position and size calculations during the relayout phase

Why is frequent DOM manipulation not recommended?

We all know that DOM manipulation is very performance intensive, so not only should we avoid DOM manipulation, but we should also reduce the number of DOM accesses.

Because in the browser, DOM and JS implementations are not done in the same engine. DOM is something that belongs in the rendering engine, and JS is something that belongs in the JS engine. When we manipulate the DOM through JS, it involves communication between two threads, which inevitably leads to some performance loss. Manipulating the DOM more than once means that threads are communicating with each other all the time, and manipulating the DOM can cause redraw backflow, which can lead to performance issues.

Think of DOM and JavaScript as islands, each connected by a toll bridge. — High Performance JavaScript

When does Reflow and Repaint occur?

Operations that cause backflow:

  • First rendering of a page (unavoidable and most expensive)
  • The browser window size changed (resize event)
  • Element size or position changes (margins, width, height, borders, etc.)
  • Element content changes (number of words or image size, etc.)
  • Element font size changes
  • Add or removevisibletheDOMThe element
  • The activationCSSPseudo classes (e.g.:hover)
  • Query some properties or call some methods

Some common properties and methods that cause backflow:

Causes backflow properties and methods
width height margin padding
display border-width border position
overflow font-size vertical-align min-height
clientWidth clientHeight clientTop clientLeft
offsetWidth offsetHeight offsetTop offsetLeft
scrollWidth scrollHeight scrollTop scrollLeft
scrollIntoView() scrollTo() getComputedStyle()
getBoundingClientRect() scrollIntoViewIfNeeded()

Why does getting some property or calling a method also cause backflow?

Because all of the above attributes and methods need to return the latest layout information, the browser has to trigger a backflow redraw to return the correct value.

Property that causes a redraw

Properties:
color border-style visibility background
text-decoration background-image background-position background-repeat
outline-color outline outline-style border-radius
outline-width box-shadow background-size

Find CSS Triggers on this website

Browser optimization mechanisms

Because each reordering causes additional computation overhead, most browsers optimize the reordering process by queuing changes and executing them in batches. The browser queues changes until a certain amount of time has passed or a certain threshold has been reached before it makes a batch change and emptens the queue. However, the queue is forced to refresh when the layout information is retrieved, for example when you access the following properties or use the following methods:

  • ClientTop, clientLeft, clientWidth, clientHeight

  • OffsetTop, offsetLeft, offsetWidth, offsetHeight

  • ScrollTop, scrollLeft, scrollWidth, scrollHeight

  • getComputedStyle()

  • getBoundingClientRect

  • You can visit this website: Paulirish

All of the above attributes and methods need to return the latest layout information, so the browser has to clear the queue and trigger a backflow redraw to return the correct value. Therefore, it is best to avoid using the attributes listed above when modifying styles, as they all refresh the render queue.

How to reduce Reflow and Repaint? (optimization)

Merger ofDOMStyle modification, adoptedcss classTo modify the

const el = document.querySelector('.box')
el.style.margin = '5px'
el.style.borderRadius = '12px'
el.style.boxShadow = '1px 3px 4px #ccc'
Copy the code

CSS class is recommended

.update{
  margin: 5px;
  border-dadius: 12px;
  box-shadow: 1px 3px 4px #ccc
}
const el = document.querySelector('.box')
el.classList.add('update')
Copy the code

If you need to access the DOM multiple times, try to cache the DOM using local variables

Avoid using a table layout because a small change can cause the entire table to be rearranged

CSS selectors match from right to left to avoid too many node hierarchies

DOM offline processing to reduce backflow redraw times

The offline DOM does not belong to any part of the current DOM tree, which means that our processing of the offline DOM does not cause backflow or redrawing of the page.

  • usedisplay: noneAs we mentioned above (display: none) completely removes elements from the render tree so that they are neither visible nor part of the layout, and subsequent operations on the DOM do not trigger backflow or redrawdisplayProperty changed to display triggers only one redraw and redraw.

Note that ⏰ : visibility: hidden elements only affect redrawing, not rearrangement.

  • throughdocumentFragmentTo create adomDocument fragment on which to batch operatedom, and then add to the document, which triggers only one rearrangement.
const el = document.querySelector('.box')
const fruits = ['front'.'nanjiu'.'study'.'code'];
const fragment = document.createDocumentFragment();
fruits.forEach(item= > {
  const li = document.createElement('li');
  li.innerHTML = item;
  fragment.appendChild(li);
});
el.appendChild(fragment);
Copy the code
  • Clone the node and replace the original node after modification
const el = document.querySelector('.box')
const fruits = ['front'.'nanjiu'.'study'.'code'];
const cloneEl = el.cloneNode(true)
fruits.forEach(item= > {
  const li = document.createElement('li');
  li.innerHTML = item;
  cloneEl.appendChild(li);
});
el.parentElement.replaceChild(cloneEl,el)
Copy the code

The DOM is detached from the normal document flow

Use absoult or Fixed to remove the element from the normal document flow. Using absolute positioning makes the element a child of the body in the rendering tree, with low rearrangement overhead and less impact on other nodes.

CSS3 Hardware acceleration (GPU acceleration)

Using CSS3 hardware acceleration, transform, opacity, and filters can be rendered without backflow redrawing. Other properties of animations, such as background-color, will still cause backflow redraw, but it can still improve the performance of those animations.

Common CSS properties that trigger hardware acceleration:

  • transform
  • opacity
  • filters
  • Will-change

Set the node to a layer

Layers prevent the rendering behavior of this node from affecting other nodes. For the video TAB, for example, the browser automatically turns the node into a layer.

Recommended reading

  • What is the difference between Promise, Generator, and Async?
  • 【Vue source code learning 】 rely on collection
  • 【Vue source code learning 】 responsive principle exploration
  • Causes and solutions of unreliable JS timer execution
  • From how to use to how to implement a Promise
  • Explains the page loading process in great detail

Original address point here, welcome to pay attention to the public number “front-end South Jiu”, reply into the group, pull you into the front exchange group to learn ~.

I’m Nan Jiu, and we’ll see you next time!!