Reflow和Repaint

  • repaint(重绘):指的是一种,不会影响当前DOM结构和布局的一种重绘动作。
  • reflow (回流): 要发生在DOM树被操作的时候,任何改变DOM结构和布局,都会产生Reflow。一个元素的reflow操作发生时,它的所有的父元素和子元素都会发生reflow,最后reflow必然会导致repaint的发生;

严重性:

  • 在性能优化的前提下,reflow的性能消耗要比repaint的大。

体现:

  • repaint是某个DOM元素进行重绘,reflow是整个页面进行重排,也就是对页面所有的DOM元素渲染。

如何触发?

  • repaint的触发:
    1. 不可见到可见(visibility样式属性);
    2. 颜色或图片的变化(background, border-color, color 样式属性;
    3. text-aligin, a:hover 也会造成重绘;
    4. 伪类引起的颜色变化不会导致页面回流,仅仅会触发重绘,不改变页面元素大小,形状和位置,但改变其外观。

  • reflow的触发:
    1. 浏览器窗口的变化;
    2. DOM节点的添加和删除操作;
    3. 一些改变页面元素的大小,形状,位置的操作会触发;
    4. DOM元素测量属性和方法也会触发reflow,如下:
    ```
    var tipWidth = tipBox.offsetWidth;//reflow
    tipScrollLeft = tipBox.scrollLeft;//reflow
    display=window.getComputedStyle(div,'').getPropertyValue('display');//reflow

      ```
    

如何尽量避免reflow?

  1. 尽可能在DOM末梢,通过设置class来修改DOM元素的style属性,尽可能减少受影响的DOM元素。
  2. 避免设置多项内联样式,使用常用的class方式进行样式设置,以避免设置样式时,访问DOM的低效率。
  3. 设置动画元素position属性值为fixed 或 absolute,这样当前动画元素由于从当前文档流中脱离出来,因此受影响的只有当前元素。
  4. 牺牲精度,满足性能:动画精度太强,会造成更多的repaint/reflow,牺牲精度,能满足性能的损耗,获取性能和动画平滑度的平衡。
  5. 避免使用table进行布局,table每个元素的大小以及内容的改变,都会造成整个table进行重新计算,造成大幅度的repaint和reflow, 改用div则可以针对性的进行repaint 和 避免不必要的reflow 。
  6. 避免在CSS中使用运算式。

通过 Reflow 和 Repaint 的介绍可知,每次 Reflow 比其 Repaint 会带来更多的资源消耗,因此,我们应该尽量减少 Reflow 的发生,或者将其转化为只会触发 Repaint 操作的代码。

var tipBox = document.createElement('div'); 
  document.body.appendChild('tipBox');//reflow
  var tip1 = document.createElement('div'); 
  var tip2 = document.createElement('div'); 
  tipBox.appendChild(tip1);//reflow 
  tipBox.appendChild(tip2);//reflow

如上的代码,会产生三次reflow,优化后的代码如下:

var tipBox = document.createElement('div');
tip1 = document.createElement('div'); 
tip2 = document.createElement('div'); 
tipBox.appendChild(tip1);
tipBox.appendChild(tip2); 
document.body.appendChild('tipBox');//reflow

当然还可以利用 display 来减少reflow次数:

var tipBox = document.getElementById('tipBox'); 
  tipBox.style.display = 'none';//reflow 
  tipBox.appendChild(tip1);
   tipBox.appendChild(tip2);
   tipBox.appendChild(tip3); 
   tipBox.appendChild(tip4); 
   tipBox.appendChild(tip5); 
   tipBox.style.width = 120; 
   tipBox.style.height = 60; 
   tipBox.style.display = 'block';//reflow
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。