Browser Reflow and Repaint

When the DOM changes affect the geometric properties of the element (width, height changes, etc.) the 
browser needs to recalculate  the geometric properties
of the element and the geometric properties of other elements in the page may be affected  . The
rendering tree changes, that is, re- The process of constructing a RenderTree rendering tree 
is called reflow

If the DOM change only affects the background color and other non-geometric properties 
, then a repaint occurs instead of a  reflow
because the layout has not changed.

Page redraw and reflow will affect performance (redraw is better), try to avoid or reduce reflow

 

trigger rearrangement

Changes in page layout and element geometry can cause reflows Reflow 
occurs in the following situations

  • page initial rendering
  • Add/remove visible DOM elements
  • change element position
  • Change element dimensions (width, height, margins, borders, etc.)
  • Change element content (text or image, etc.)
  • Change window size

The scope and degree of rearrangement will be different under different conditions. 
In some cases, the entire page may even be rearranged, such as sliding the scroll bar.

Browser Optimization: Render Queue

  1.     div.style.left = '10px';
  2.     div.style.top = '10px';
  3.     div.style.width = '20px';
  4.     div.style.height = '20px';

As above, the left, top, width, and height properties of the element are modified to 
meet the conditions for our reflow.  In
theory, 4 reflows will occur, 
but in fact, only 1 reflow will occur. 
This is because our modern browsers have rendering Queue mechanism 
When I change a style of an element, it will cause the browser to reorder or redraw. 
It will enter a rendering queue 
and then the browser will continue to look down. If there is a style modification below, 
it will also enter the queue 
until there is no style below . Modify the 
browser to optimize the rearrangement process according to the batch execution of the rendering queue, and modify the style to optimize 
the 4 times of rearrangement to 1 time.

    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);

As above, 4 rearrangements of
offsetLeft/Top/Width/Height will force the queue to be refreshed and require the style modification task to be executed immediately. 
This makes sense. 
After all, the browser is not sure whether you will modify the same style in the next code in 
order to Guaranteed to get the correct value, it has to execute the render queue immediately to trigger the reorder

The following properties or methods flush the render queue

  • offsetTop、offsetLeft、offsetWidth、offsetHeight
  • clientTop、clientLeft、clientWidth、clientHeight
  • scrollTop、scrollLeft、scrollWidth、scrollHeight
  • getComputedStyle()(IE中currentStyle)

In the process of modifying the style, we should try to avoid using the above properties

Performance optimization for redraw and reflow

Separate read and write operations

Knowing the principle, we can optimize the above code

  1. div.style.left = '10px';
  2. div.style.top = '10px';
  3. div.style.width = '20px';
  4. div.style.height = '20px';
  5. console.log(div.offsetLeft);
  6. console.log(div.offsetTop);
  7. console.log(div.offsetWidth);
  8. console.log(div.offsetHeight);

There is only one rearrangement, and the reason is believed to be clear 
to everyone. Move all read operations after all write operations 
 

style change

or the code where we originally modified the style

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

As above, although modern browsers have an optimization mechanism for rendering queues,
ancient browsers are still inefficient, triggering 4  reflows
. Even so, we can still make optimizations. 
We need the cssText property to merge all style changes

    div.style.cssText = 'left:10px;top:10px;width:20px;height:20px;';
As above, only need to modify the DOM once and process it together, 
only triggering 1 reflow 
and only one line of code, see looks relatively clean

Note that cssText will overwrite the existing interline style 
. If you want to keep the original interline style, the following
    div.style.cssText += ';left:10px;';

In addition to cssText, we can also modify the style by modifying the class name, as follows
div.className = 'new-class';
this method is maintainable and can also help us avoid 
the small performance impact of the display code , changing the class needs to check the cascading style, but conforming to the BEM standard can better decouple and increase maintainability. It is recommended to write
div.className = 'js-class';

Cache layout information

I think caching is a panacea, and any performance optimization is indispensable
    . div.style.left = div.offsetLeft + 1 + 'px';
    div.style.top = div.offsetTop + 1 + 'px';
As above, this kind of reading Executing the write operation after the operation causes 2 rearrangements of the 
cache, which can be optimized

    var curLeft = div.offsetLeft;
    var curTop = div.offsetTop;
    div.style.left = curLeft + 1 + 'px';
    div.style.top = curTop + 1 + 'px';
As above, this is also equivalent to separate reading Write operations are 
optimized to 1 rearrangement

Element batch modification

Now we want to add a lot of li to the ul in a loop 
(if the ul doesn't already exist, the best way is to add the li to the ul in a loop, and then add the ul to the document, 1 rearrangement)
var ul = document.getElementById( 'demo');
for(var i = 0; i < 1e5; i++){
    var li = document.createElement('li');
    var text = document.createTextNode(i);
    li.appendChild(text); ul. appendChild(li);
}

我可以做出下面的优化
var ul = document.getElementById('demo');
ul.style.display = 'none';
    for(var i = 0; i < 1e5; i++){
        var li = document.createElement('li');
        var text = document.createTextNode(i);
        li.appendChild(text); ul.appendChild(li);
    }
ul.style.display = 'block';

var ul = document.getElementById('demo');
var frg = document.createDocumentFragment();
for(var i = 0; i < 1e5; i++){
    var li = document.createElement('li');
    var text = document.createTextNode(i);
    li.appendChild(text); frg.appendChild(li);
}
ul.appendChild(frg);

var ul = document.getElementById('demo');
var clone = ul.cloneNode(true); 
for(var i = 0; i < 1e5; i++){
    var li = document.createElement('li');
    var text = document.createTextNode(i);
    li.appendChild(text); clone.appendChild(li); 
}
ul.parentNode.replaceChild(clone,ul);

The principle of the above method to reduce redraw and rearrangement is very simple

  • Element out of document
  • change style
  • Element regression documentation

And changing the element uses
Hidden Element
Document Fragment
Clone Element  respectively

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325461459&siteId=291194637