關於迴流和重繪在剛開始學習前端時一般不會太在意,因爲其影響的大多是運行時的性能問題。
顯然,頻繁地進行迴流和重繪會導致運行性能的下降,所以,在要求性能的時候,往往要注意減少頁面的迴流和重繪。
概念
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。