回流(reflow):指的是網絡瀏覽器為了重新渲染部分或全部的文檔而重新計算文檔中元素的位置和幾何結構的過程。
頁面上節點是以樹的形式展現的,我們通過js將頁面上的一個節點刪除,此時為了不讓剩下的節點脫節,將斷點結合起來重新形成一棵樹。而這個重新結合過程就是回流。就是由於某些修改,要將元素回過頭來重新“流”一遍。
重繪(repaints):是一個元素外觀的改變所觸發的瀏覽器行為,例如改變vidibility、outline、背景色等屬性。瀏覽器會根據元素的新屬性重新繪制,使元素呈現新的外觀。
重繪不會帶來重新布局,並不一定伴隨回流。回流是更明顯的一種改變,渲染樹需要重新計算;回流的危害在於重新對DOM樹進行渲染,那么,脫離文檔流之后,進行的任何操作,都不會造成回流了!如果沒有對頁面進行優化,減少大量回流,那么頁面因為回流所花費的時間,導致用戶體驗感大打折扣;只要修改DOM或修改了元素的形狀或大小,就會觸發Reflow,單純修改元素的顏色只需Repaint一下(調用操作系統Native GUI的API繪制)。
減少回流的幾點建議:
1. 減少不必要的DOM深度。因為無論你改變DOM節點樹上任何一個層級都會影響節點樹的每個層級——從根結點一直到修改的子節點。不必要的節點深度將導致執行回流時花費更多的時間。
2. 精簡css,去除沒有用處的css
3. 如果你想讓復雜的表現發生改變,例如動畫效果,那么請在這個流動線之外實現它。使用position-absolute或position-fixed來實現它,也即是讓其脫離文檔流,不影響父級;現代瀏覽器也可以使用CSS3 transition實現動畫效果,比改變像素值來的高性能。
4. 避免不必要的復雜的css選擇符,尤其是使用子選擇器,或消耗更多的CPU去做選擇器匹配。
5.頁面的元素適當定高,例如如果div內容可能有高度差異的動態內容載入; 頁面刷新載入的時候,應避免頁面元素的晃動、位移等,這些都是額外的重繪,會讓你的CPU和風扇興奮的
6.圖片設定不響應重繪的尺寸,如果你的<img>不設定尺寸、同時外部容器沒有定死高寬,則圖片在首次載入時候,占據空間會從0到完全出現,左右上下都可能位移,發生大規模的重繪。可以參見新浪微博載入時候頁面高度隨着圖片顯示不斷變高的問題,這些都讓瀏覽器重繪了,一是體驗可能不好,二是燒CPU的。
html頁面的加載理解
瀏覽器接收到html代碼,可能是一份完整的文檔,也可能是一個chunk,即開始解析。解析過程是先構建dom樹,再根據dom樹構建渲染樹,最后瀏覽器將渲染樹繪制到頁面上。
構建dom樹的過程即根據html代碼自上而下進行構建,當遇到script文件加載/執行會阻塞后面dom樹的構建(javascript可能會改變dom樹),而遇到css文件則會阻塞渲染樹的構建,即dom樹依然繼續構建(除非遇到script標簽並且css文件依舊未加載完成),但不會渲染繪制到頁面上。而無論哪個阻塞,該加載的文件還是會加載,例如html文檔中的其他css/js/圖片文件。
另外javascript被加載后就會被執行,執行的過程也阻塞樹的構建。是執行完了才解析其他內容,而不是執行完了才加載其他內容。
