首先,咱們先來了解一下瀏覽器的渲染過程是什麼樣的,也就是說瀏覽器把一堆代碼呈現到頁面上的過程是什麼樣子的,根據下圖,咱們能夠總結出瀏覽器的渲染步驟爲:
步驟:css
Render Tree相似於DOM Tree,但存在很大的區別:Render Tree可以識別樣式,Render Tree中的每一個節點都有本身的樣式,並且Render Tree不包含隱藏的節點,好比display:none的節點,由於這些節點不會用於頁面呈現。瀏覽器
————分割線————
在步驟2中,渲染樹(Render Tree)是若是構建的呢?
如上圖所示,總結出的構建步驟爲:佈局
遍歷的是每一個可見節點,那麼不可見的節點包括:
(a)一些不會渲染輸出的節點,好比script、meta、link等;
(b)一些經過css進行隱藏的節點。好比display:none。注意,利用visibility和opacity隱藏的節點,仍是會顯示在渲染樹上的。只有display:none的節點纔不會顯示在渲染樹上。網站
又是怎麼組合的呢?
簡單是就是一個匹配的過程,要將每一個HTML元素節點與之正確的樣式相匹配。由於節點位置屬性將經過CSS選擇器鏈的優先級來決定,渲染樹中的某個結點可能會同時知足多個選擇器鏈,這時候就要經過選擇器的優先級來完成屬性的賦值。
這時候,將渲染結點同時知足的幾個選擇器鏈經過其優先級加權算值,從小到大依次覆蓋渲染結點;而如何肯定此渲染結點是否知足某個選擇器鏈呢?這也是一個逐層判斷的過程:今後渲染結點開始,判斷此結點是否與選擇器鏈表的當前選擇器相匹配。若是匹配,判斷此選擇器與下一個選擇器的關係:若是爲NONE,表示本選擇器是選擇器鏈的最後一個,返回成功;若是關係爲AND (好比:#id.class),選擇下一個選擇器與本渲染結點繼續比較;若是關係爲CHILD,表示本選擇器是下一個選擇器的子結點,返回下一個選擇器與下一個渲染結點的匹配結果;不然,關係爲DESCENDANT,選擇器和渲染結點各指向下一個結點,而後將渲染結點繼續回溯,直到第一個知足回溯後的選擇器的結點,此時將繼續判斷回溯後的選擇器和回溯後的渲染結點是否匹配。
————分割線————spa
什麼是重繪呢?當Render Tree中的一些元素須要更新屬性,而這些屬性只是影響元素的外觀、風格,而不會影響佈局的,好比改變背景顏色等,這就會引發瀏覽器重繪(Painting)。
例如:
某網站首頁頁面中,將藍色框內導航欄的背景顏色變爲粉色,其餘的不變,並無改變總體佈局和各個部分的位置,因此此時會引發重繪,不會引發迴流。3d
當Render Tree中的部分節點由於元素的尺寸、佈局、隱藏等改變而須要從新構建,這就會引發瀏覽器迴流(reflow)。每一個頁面至少須要一次迴流,就是在頁面第一次加載的時候(瀏覽器渲染過程步驟3),由於要第一次構建Render Tree。在迴流的時候,瀏覽器會使渲染樹中受到影響的部分失效,並從新構造這部分渲染樹,完成迴流後,瀏覽器會從新繪製受影響的部分到屏幕中,即重繪。
例如:
某網站首頁頁面中,將藍色框內導航欄直接刪掉,則下面的全部部分會進行上移,總體的佈局發生了變化,因此此時會引發迴流,接着進行重繪。
【在這裏引出了迴流與重繪的一個最大的區別:
迴流必定會引發重繪,重繪不必定會引發迴流 】
什麼時候會觸發迴流重繪呢?
(a)添加或刪除可見的DOM元素;
(b)元素的位置發生變化;
(c)元素的尺寸發生變化(包括外邊距、內邊框、邊框大小、高度和寬度等);
(d)內容發生變化,好比文本變化或圖片被另外一個不一樣尺寸的圖片所替代;
(e)頁面一開始渲染的時候(這確定避免不了);
(f)瀏覽器的窗口尺寸變化(由於迴流是根據視口的大小來計算元素的位置和大小的)......blog
【做者水平有限,歡迎你們在評論區交流指正~】圖片