關於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。

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