Many people know how to reduce browser reordering and redrawing, but they don’t know exactly how it works and how to do it, and they are still confused when the topic comes up. I hope you can bear to read this article, carefully consider, thoroughly master this knowledge point!

Blog, front-end accumulation of documents, public number, GitHub

Web page generation process:

  1. The HTML is parsed into a DOM tree by the HTML parser
  2. CSS is parsed into a CSSOM tree by a CSS parser
  3. Generate a Render Tree by combining DOM Tree and CSSOM Tree
  4. Generate a layout (flow), which is a planar composition of all nodes of the rendered tree
  5. Paint the layout on the screen

Steps 4 and 5 are the most time-consuming, and together they are what we call rendering.

I found a picture online that I annotated to make it more intuitive:


Render:

When a web page is generated, it is rendered at least once.

It is constantly re-rendered as the user accesses it

Rerendering requires either repeating the previous step 4 (regenerating the layout)+ step 5 (redrawing) or just step 5 (redrawing).

The rearrangement proportion is drawn large:

Big, in this context, means: Who can influence whom?

  • Redraw: the appearance of some elements has been changed, for example, the element’s fill color
  • Rearrange: Regenerate the layout and rearrange the elements.

As with the concept above, simply changing the appearance of the elements will not cause the layout of the page to be redrawn, but when the browser completes the rearrangement, it will redraw the parts affected by the rearrangement.

For example, if you change the height of an element, the element and the surrounding DOM need to be redrawn.Copy the code

In other words, “redraw” doesn’t necessarily result in “rearrange”, “rearrange” necessarily results in “redraw”

Rearrangement (reflow) :

Concept:

When a DOM change affects the element’s geometry (the position and size of the DOM object), the browser needs to recalculate the element’s geometry and place it in the correct position in the interface, a process called rearrangement.

Rearrangement is also known as backflow, and the rearrangement process is more clearly understood in the following way:

Backflow is like throwing a stone into the river (the document flow) (dom change), causing ripples and then ripples in the surrounding water, hence the name backflow

It is common to cause rearrangements of properties and methods

Any operation that changes the geometry of an element (its position and size) triggers a rearrangement. Here are some examples:

  1. Add or remove visible DOM elements
  2. Element size changes — margins, padding, borders, width, and height
  3. Content changes, such as the user entering text in an input box
  4. Browser window size changes – when the resize event occurs
  5. Calculate the offsetWidth and offsetHeight properties
  6. Sets the value of the style property
It is common to cause rearrangements of properties and methods
width height margin padding
display border position overflow
clientWidth clientHeight clientTop clientLeft
offsetWidth offsetHeight offsetTop offsetLeft
scrollWidth scrollHeight scrollTop scrollLeft
scrollIntoView() scrollTo() getComputedStyle()
getBoundingClientRect() scrollIntoViewIfNeeded()

Rearrangement of areas of influence:

Since the browser rendering interface is based on the run-off layout model, rearrangement of the surrounding DOM can be effected in two ways:

  • Global scope: from the root nodehtmlStart rearranging the entire render tree.
  • Local scope: Rearrange a part of the render tree or a render object

Global scope rearrangement:

<body>
  <div class="hello">
    <h4>hello</h4>
    <p><strong>Name:</strong>BDing</p>
    <h5>male</h5>
    <ol>
      <li>coding</li>
      <li>loving</li>
    </ol>
  </div>
</body>
Copy the code

When reflow occurs on the P node, hello and body are also re-rendered, and even H5 and OL are affected.

Local range rearrangement:

To explain this in terms of local layout, you can freeze geometric information such as the width and height of a DOM, and then trigger a rearrangement within the DOM, which will only re-render the elements inside the DOM without affecting the outside world.

Reduce the number and scope of rearrangement as much as possible:

The rearrangement requires an update to the render tree, which is costly in performance:

They are costly, they destroy the user experience, they make the UI presentation very slow, and we need to minimize the number of rearrangements triggered.

The performance cost of rearrangement depends on how many nodes in the render tree need to be rebuilt:

So we should try to organize the HTML structure in a local layout with as little impact as possible on the scope of the rearrangement.

Rather than stacking labels like the global-scoped example code, any element that triggers a rearrangement will result in a global-scoped rearrangement.

Redraw (repaint) :

Concept:

The process of redrawing an element when its appearance is changed without changing its layout is called redrawing.

Common attributes that cause redraw:

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

Browser render queue:

How many renders will the following code trigger?

div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
Copy the code

According to our definition above, this code theoretically triggers four rearrangements + redraws, because each one changes the geometry of the element, but in reality only triggers one rearrangement, thanks to the browser’s rendering queue mechanism:

When we modify the geometry of an element, causing the browser to trigger a rearrangement or redraw. It puts the action into the render queue, and when the number of actions in the queue reaches a certain number of times, the browser executes them in batches.

Force refresh queue:

div.style.left = '10px';
console.log(div.offsetLeft);
div.style.top = '10px';
console.log(div.offsetTop);
div.style.width = '20px';
console.log(div.offsetWidth);
div.style.height = '20px';
console.log(div.offsetHeight);
Copy the code

This code triggers four rearranges and redraws, because whenever you request the styling information in the Console, the browser will immediately perform the task of rendering the queue, even if the value is not related to the value you changed during the operation.

Since there may be operations in the queue that affect these values, the browser will immediately rearrange + redraw to give us the most accurate values.

Force refresh queue style request:

  1. offsetTop, offsetLeft, offsetWidth, offsetHeight
  2. scrollTop, scrollLeft, scrollWidth, scrollHeight
  3. clientTop, clientLeft, clientWidth, clientHeight
  4. GetComputedStyle (), or currentStyle of IE

In development, we should use these style requests carefully, pay attention to the context, avoid a line of code rearrangement, which can be a huge performance drain

Rearrange optimization suggestions

As mentioned above, we should reduce the number of rearrangements and the range of rearrangements as much as possible. This is very extensive. Here are some effective suggestions for your reference.

1. Separate read and write operations

div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
console.log(div.offsetLeft);
console.log(div.offsetTop);
console.log(div.offsetWidth);
console.log(div.offsetHeight);
Copy the code

The code above triggers 4 rearrangements + redraw, this time only triggers 1 rearrangement:

On the first console, the browser cleared the render queue for the previous four writes. The rest of the console, since the render queue is empty, does not trigger a reorder, just fetching values.

2. Style set changes

div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
Copy the code

Although most browsers now have render queue optimization, some browsers and older browsers are still inefficient:

It is recommended to change the style by changing the class or CSSText property set

// bad
var left = 10;
var top = 10;
el.style.left = left + "px";
el.style.top  = top  + "px";
// good 
el.className += " theclassname";
// good
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
Copy the code

3. Cache layout information

// bad forces the refresh to trigger two rearrangements
div.style.left = div.offsetLeft + 1 + 'px';
div.style.top = div.offsetTop + 1 + 'px';

// good Cache layout information is equivalent to read-write separation
var curLeft = div.offsetLeft;
var curTop = div.offsetTop;
div.style.left = curLeft + 1 + 'px';
div.style.top = curTop + 1 + 'px';
Copy the code

4. Change the DOM offline

  • Hide the DOM to manipulate

    Hide the DOM with display until the DOM is manipulated, and make the display attribute of the element visible only after the manipulation is complete, because invisible elements do not trigger rearrangements and redraws.

    dom.display = 'none'
    // Modify the DOM style
    dom.display = 'block'
    Copy the code
  • Creating a DOM fragment using a DocumentFragment, batching the DOM on it, and then adding it to the document only triggers a rearrangement.

  • Copy the node, work on the copy, and then replace it!

5. The position attribute is Absolute or Fixed

If the position attribute is absolute or fixed, the rearrangement cost is relatively small and its influence on other elements is not considered

6. Optimize the animation

  • You can apply animation effects to elements with position attributes such as Absolute or fixed with little impact on other elements

    Animation effects should also sacrifice some smoothness for speed, and the balance should be measured by yourself:

    For example, implementing an animation that moves at 1 pixel is the smoothest, but reflow is too frequent, consuming CPU resources, and moving at 3 pixels is much better.

  • Enable GPPU acceleration

    This part comes from optimizing CSS rearrangement redraw with browser performance

    GPU(Image Accelerator) :

    GPU hardware acceleration refers to the application of GPU graphics performance to some graphics operations in the browser to be completed by GPU, because GPU is specially designed for processing graphics, so it is more efficient in speed and energy consumption.

    GPU acceleration typically consists of the following components: Canvas2D, Layout Composition, CSS3 Transitions, CSS3 3D Transforms, WebGL, and Video.

    /* * Change 2d Transform to 3D * to force GPU acceleration * improve animation performance */
    div {
      transform: translate3d(10px, 10px, 0);
    }
    Copy the code

conclusion

Rearrangement is also one of the key factors that can lead to inefficient DOM script execution. Rearrangement and redrawing are frequent interview problems in large companies and involve performance optimization, which is one of the basic concepts/skills that the front-end must master (type on the blackboard!). .

This is inevitable, but when we develop, we should try to organize the code according to the suggestions in the article. This kind of optimization needs to be done consciously at ordinary times, bit by bit, and I hope you pay attention to it.

I hope the friends can click like/follow, your support is the biggest encouragement to me.

Blog, front-end accumulation of documents, public number, GitHub

The above 2018.12.17

References:

Page performance management details

Optimized CSS rearrangement redraw with browser performance