关于Repaint(重绘)与Reflow(回流)

关于回流和重绘在刚开始学习前端时一般不会太在意,因为其影响的大多是运行时的性能问题。
显然,频繁地进行回流和重绘会导致运行性能的下降,所以,在要求性能的时候,往往要注意减少页面的回流和重绘。


概念

repaint重绘

不会改变DOM的排版,仅仅改变某个元素的一些表现。比如,字体颜色的变化,背景颜色,透明度,输入框的值的改变等等。

reflow回流

这个相较于重绘的改动更大。当DOM的排版改变时,会触发重绘。因此,改变某个元素的长宽,显示与否(display),以及浏览器窗口大小改变,字体大小改变,获取浏览器属性值(offsetHeight、offsetWidth),滚动页面,DOM操作等。


如何减少

  • 尽可能在DOM末梢通过改变class来修改元素的style属性:尽可能的减少受影响的DOM元素。
<div class='outer'>
    <div class='inner'>abc</div>
</div>
outer = document.getElementsByClassName('outer');
inner = document.getElementsByClassName('inner');
//bad
outer.style.color = 'red';
//good
inner.style.color = 'red';

显然,两种方式都改变了“abc”的颜色,但是通过最里面那层改变导致的重绘范围将更小。

  • 避免设置多项内联样式:使用常用的class的方式进行设置样式,以避免设置样式时访问DOM的低效率。
//bad
inner.style.color = 'red';
inner.style.backgroundColor = 'blue';
...
//good
.newClass {
    color: red;
    background-color: blue;
    ...
}
inner.className += 'newClass';
//jquery
inner.css({'color': 'red', 'background-color': 'blue'});

上面第一种方法,分多步对一个元素的样式进行了修改,这样每一步都会导致重绘,性能自然降低。
而第二种和第三种方法,将需要改变的样式放在一个class中或者一次性改变,只会发生一次重绘,性能更好。

  • 设置动画元素position属性为fixed或者absolute:由于当前元素从DOM流中独立出来,因此受影响的只有当前元素,元素repaint。

  • 牺牲平滑度满足性能:动画精度太强,会造成更多次的repaint/reflow,牺牲精度,能满足性能的损耗,获取性能和平滑度的平衡。

  • 避免使用table进行布局:table的每个元素的大小以及内容的改动,都会导致整个table进行重新计算,造成大幅度的repaint或者reflow。改用div则可以进行针对性的repaint和避免不必要的reflow。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章