You will learn:

What is backflow what is redraw when does backflow happen when does redraw happen how do you avoid backflow and redrawCopy the code

With the above questions in mind, let’s find out

What is reflux

Reflow: Reflow

Reflow occurs when part (or all) of a Render tree needs to be rebuilt due to changes in element size, layout, hiding, etc.Copy the code
  • Each page flows back at least once, that is, the first time the page is loaded
  • When backflow occurs, the browser invalidates the affected portion of the render tree and reconstructs that portion of the render tree
  • After the backflow is complete, the browser redraws the affected parts, a redrawing process

What is redraw

Repaints: English, repaints

Repaints are called when elements in a Render tree need to be updated with attributes that only affect the appearance, style of the element, but not the layout (e.g. background-color).Copy the code

Features: backflow will cause redrawing, redrawing does not necessarily cause backflow backflow is more expensive than drawing

When reflux occurs

Backflow is required when the page layout and geometry properties change

Browser backflow occurs when:

(1) Add or remove visible DOM elements; (2) Element position changes; (3) Element size changes -- margins, padding, borders, width and height. (4) Content changes -- such as changes in text or image size resulting in changes in the width and height of calculated values. (5) Initialization of page rendering; (6) The browser window size changes -- when the resize event occurs;Copy the code
let box = document.getElementById("box").style;
box.padding = "2px"; // Backflow + redraw box.border ="1px solid red"; // Redraw box. FontSize ="14px"; // redraw document.getelementById ("box").appendChild(document.createTextNode('abc! '));
Copy the code

When redraw occurs

The attribute or style of the element changes.

let box = document.getElementById("box").style;
box.color = "red"; // Redraw box.backgroud-color ="blue"; / / redraw document. GetElementById ("box").appendChild(document.createTextNode('abc! '));
Copy the code

Because of the overhead of backflow, if every operation backflow redraws, the browser may not be able to bear it. So many browsers optimize these actions.

Multiple reflow, redraw into a single reflow redraw:

The browser maintains a queue and places all operations that cause backflow and redraw in this queue. When the number of operations in the queue reaches a certain number of times or at a certain interval, the browser flushes the queue and performs a batch.Copy the code

But sometimes the above method fails because:

In some cases, the browser may be forced to flush the queue when the request requests some style information from the browser, such as: (1) offsetTop, offsetLeft, offsetWidth, OffsetHeight scrollTop/Left/Width/Height (2) (3) clientTop/Left/Width/Height (4) the Width, Height (5) request the getComputedStyle (), Or currentStyle of IECopy the code

When you request some of the above attributes, the browser needs to flush the queue in order to give you the most accurate values, because there may be operations in the queue that affect those values. Even if you get an element’s layout and style information unrelated to the most recent or changed layout information, the browser forces the render queue to refresh.

As a result, browser optimization is not enough, so we need some way to avoid or reduce browser backflow and redraw as much as possible

How to avoid, reduce backflow and redraw

  • Reduce render Tree operations [incorporating multiple DOM and style changes]
  • Reduce requests for style information and take advantage of the browser’s optimization strategies
(1) Add CSS styles instead of using JS control styles (2) Make the element to be handled "offline" and updated together after processingcloneNode(true or false) and the replaceChild technique, which causes a backflow and redraw (3) directly change the className, if the style is changed dynamically, use cssText (consider not optimized browsers) // bad em.style.left = x +"px";
    elem.style.top = y + "px";
    // good
    elem.style.cssText += "; left: " + x + "px; top: " + y + "px;"; (4) Do not frequently access attributes that cause browser flush queues. If you do, use cache // badfor (var i = 0; i < len; i++) {
      el.style.left = el.offsetLeft + x + "px";
      el.style.top = el.offsetTop + y + "px";
    }
    // good
    var x = el.offsetLeft,
        y = el.offsetTop;
    for (var i = 0; i < len; i++) {
      x += 10;
      y += 10;
      el.style = x + "px";
      el.style = y + "px"; } (5) Remove elements from the animation stream, reduce the size of the Render Tree ("#block1").animate({left:50});
    $("#block2").animate({marginLeft:50}); (6) Set the position attribute to absolute or fixed for the element that needs to be rearranged several times, so that the element is removed from the document flow and its change will not affect other elements. For example, animate elements are best set to absolute positioning; (7) Avoid table layout: Try not to use form layout, if there is no fixed width form the width of a column is determined by the width of a column, it is likely in the last line is beyond the width of the previous column width, cause the overall reflux create table may need to repeatedly calculation to determine the node in the render tree attributes, it usually takes three times in the time of the same element. (8) Try to complete all operations that need to change the DOM at oncelet box = document.getElementById("box").style;
    // bad
    box.color = "red"; // Redraw box. Size ="14px"; // redraw // good box.bord ='1px solid red'(9) Change the class at the end of the DOM tree whenever possible, and change the class inside the DOM tree whenever possible (to limit the scope of backflow). (10) Avoid using JavaScript expressions in IECopy the code

References:

  • Front step (ii) redraw and reflow
  • Redraw and reflow
  • Page redraw and reflow, and how to optimize