迴流(reflow)和重繪(repaint)

首先先介紹瀏覽器解析的工作原理:


1.解析HTML文檔建立dom樹
2.解析CSS(包含外部css以及js生成的)構建渲染樹,計算出節點的樣式
3.佈局渲染樹,以根節點遞歸調用,計算每一個節點的大小,位置等,給出每一個節點出現在屏幕的精準目標
4.繪製渲染樹,遍歷渲染樹,每個幾點使用ui後端層來繪製


可以看出,reflow和repaint分別出現在3/4步,現在我們給出定義:


根據dom結構中,每個元素都有自己的盒子,這些需要瀏覽器根據各種樣式(瀏覽器的/開發人員定義的)來計算並根據結果將元素放置在該出現的位置,這個過程稱之reflow(設置頁面佈局),每個頁面至少需要完成一次迴流,就是頁面加載的時候
當各種盒子的位置/大小/以及其它屬性都確定下來後,瀏覽器於是便把這些元素都按照各自的特性繪製一遍,於是頁面的內容出現了,這個過程稱之爲repaint,當渲染樹中某些元素更新一些隻影響元素外觀風格的屬性,而不影響佈局,比如background-color,這個過程就是重繪。


注意: 
1.迴流必將引起重繪,重繪不一定引起迴流
2.迴流的成本比重繪的成本高很多
3.display:none 會引起迴流,visibility:hidden 只會引起重繪,因爲位置沒有改變


所以我們可以得出結論:
repaint的發生僅僅是在元素的外觀發生變化而佈局沒有改變的情況下
reflow發生在dom結構發生改變
eg:
1.dom元素的添加,修改,刪除(reflow+repaint)
2.僅僅改變dom元素的字體顏色(repaint)
3.window的resize(reflow+repaint)
4.滾動滾動條(reflow+repaint)
5.應用新的樣式


reflow & repaint的開銷是非常大的,所以在開發中應該注意:
1.避免多次設置行內樣式,避免分別單獨設置樣式,這都會多次觸發reflow
2.使用classname,classname可以滿足多個樣式一次修改,只進行一次reflow
3.當要批量操作一個dom樹時,可以將其現在dom樹中刪除,帶操作完成後,在添加到文檔樹,避免多次reflow
4.當某一區域需要頻繁地操作dom時,可以將其外部包裹一個fixed或者absolute佈局
5.避免使用table佈局,因爲table佈局一旦觸發reflow,就會導致table裏所有其他元素reflow
6.使用display:none;只引起兩次迴流和重繪
7.如果需要創建多個DOM節點,可以使用DocumentFragment創建完後一次性的加入document  
var fragment = document.createDocumentFragment();
fragment.appendChild(document.createTextNode('keenboy test 111'));
fragment.appendChild(document.createElement('br'));
fragment.appendChild(document.createTextNode('keenboy test 222'));
document.body.appendChild(fragment);



發佈了91 篇原創文章 · 獲贊 6 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章