瀏覽器渲染原理及流程

發表於2017-05-26

我們可能都知道瀏覽器含有一個渲染引擎,用來渲染視窗所展示的內容。預設情況下,渲染引擎可以顯示html、xml文件及圖片,它也可以藉助外掛(一種瀏覽器擴充套件)顯示其他型別資料,例如使用PDF閱讀器外掛,用於顯示PDF格式。但是其具體的渲染原理和流程估計也有很多人都不知道或者不清楚吧。這些天研究了一下瀏覽器的渲染原理,有了些心得,在這裡跟大家分享一下,這裡只討論渲染引擎最主要的用途——顯示應用了CSS之後的html及圖片。

渲染引擎簡介

本文所討論的瀏覽器——Firefox、Chrome和Safari是基於兩種渲染引擎構建的,Firefox使用Geoko——Mozilla自主研發的渲染引擎,Safari和Chrome都使用webkit。

渲染主流程

渲染引擎首先通過網路獲得所請求文件的內容,通常以8K分塊的方式完成。下面是渲染引擎在取得內容之後的基本流程:

解析html以構建dom樹 -> 構建render樹 -> 佈局render樹 -> 繪製render樹

這裡先解釋一下幾個概念,方便大家理解:

DOM Tree:瀏覽器將HTML解析成樹形的資料結構。

CSS Rule Tree:瀏覽器將CSS解析成樹形的資料結構。  

Render Tree: DOM和CSSOM合併後生成Render Tree。

layout: 有了Render Tree,瀏覽器已經能知道網頁中有哪些節點、各個節點的CSS定義以及他們的從屬關係,從而去計算出每個節點在螢幕中的位置。

painting: 按照算出來的規則,通過顯示卡,把內容畫到螢幕上。

reflow(迴流):當瀏覽器發現某個部分發生了點變化影響了佈局,需要倒回去重新渲染,內行稱這個回退的過程叫 reflow。reflow 會從這個 root frame 開始遞迴往下,依次計算所有的結點幾何尺寸和位置。reflow 幾乎是無法避免的。現在介面上流行的一些效果,比如樹狀目錄的摺疊、展開(實質上是元素的顯 示與隱藏)等,都將引起瀏覽器的 reflow。滑鼠滑過、點選……只要這些行為引起了頁面上某些元素的佔位面積、定位方式、邊距等屬性的變化,都會引起它內部、周圍甚至整個頁面的重新渲 染。通常我們都無法預估瀏覽器到底會 reflow 哪一部分的程式碼,它們都彼此相互影響著。

repaint(重繪):改變某個元素的背景色、文字顏色、邊框顏色等等不影響它周圍或內部佈局的屬性時,螢幕的一部分要重畫,但是元素的幾何尺寸沒有變。

注意:(1)display:none 的節點不會被加入Render Tree,而visibility: hidden 則會,所以,如果某個節點最開始是不顯示的,設為display:none是更優的。   

(2)display:none 會觸發 reflow,而 visibility:hidden 只會觸發 repaint,因為沒有發現位置變化。

(3)有些情況下,比如修改了元素的樣式,瀏覽器並不會立刻reflow 或 repaint 一次,而是會把這樣的操作積攢一批,然後做一次 reflow,這又叫非同步 reflow 或增量非同步 reflow。但是在有些情況下,比如resize 視窗,改變了頁面預設的字型等。對於這些操作,瀏覽器會馬上進行 reflow。 

來看看webkit的主要流程:

http://taligarsiel.com/Projects/webkitflow.png

再來看看Geoko的主要流程:

http://taligarsiel.com/Projects/image008.jpg

Gecko 裡把格式化好的可視元素稱做“幀樹”(Frame tree)。每個元素就是一個幀(frame)。 webkit 則使用”渲染樹”這個術語,渲染樹由”渲染物件”組成。webkit 裡使用”layout”表示元素的佈局,Gecko則稱為”reflow”。Webkit使用”Attachment”來連線DOM節點與視覺化資訊以構建渲染樹。一個非語義上的小差別是Gecko在HTML與DOM樹之間有一個附加的層 ,稱作”content sink”,是建立DOM物件的工廠。

儘管Webkit與Gecko使用略微不同的術語,這個過程還是基本相同的,如下:

1. 瀏覽器會將HTML解析成一個DOM樹,DOM 樹的構建過程是一個深度遍歷過程:當前節點的所有子節點都構建好後才會去構建當前節點的下一個兄弟節點。

2. 將CSS解析成 CSS Rule Tree 。

3. 根據DOM樹和CSSOM來構造 Rendering Tree。注意:Rendering Tree 渲染樹並不等同於 DOM 樹,因為一些像Header或display:none的東西就沒必要放在渲染樹中了。

4. 有了Render Tree,瀏覽器已經能知道網頁中有哪些節點、各個節點的CSS定義以及他們的從屬關係。下一步操作稱之為layout,顧名思義就是計算出每個節點在螢幕中的位置。

5. 再下一步就是繪製,即遍歷render樹,並使用UI後端層繪製每個節點。

注意:上述這個過程是逐步完成的,為了更好的使用者體驗,渲染引擎將會盡可能早的將內容呈現到螢幕上,並不會等到所有的html都解析完成之後再去構建和佈局render樹。它是解析完一部分內容就顯示一部分內容,同時,可能還在通過網路下載其餘內容

相關文章