【乾貨】十分鐘讀懂瀏覽器渲染流程

在以前寫過的一篇《"天龍八步"細說瀏覽器輸入URL後發生了什麼》一文中,和你們分享了從在瀏覽器中輸入網址URL到最終頁面展現的整個過程。部分讀者向我反饋對於最後的瀏覽器渲染布局這塊不是很清晰,因此本文就瀏覽器渲染流程單獨開篇講解,但願你們都能有新的收穫。javascript

瀏覽器主要組件結構css

圖片描述
(瀏覽器主要組件)html

渲染引擎——webkit和Gecko
Firefox使用Geoko——Mozilla自主研發的渲染引擎。java

Safari和Chrome都使用webkit。Webkit是一款開源渲染引擎,它原本是爲linux平臺研發的,後來由Apple移植到Mac及Windows上。linux

本文我主要以webkit渲染引擎來說解,儘管webkit和Gecko使用的術語稍有不一樣,他們的主要流程基本相同。git

圖片描述

(webkit渲染引擎流程)github

關鍵渲染路徑web

關鍵渲染路徑是指瀏覽器從最初接收請求來的HTML、CSS、javascript等資源,而後解析、構建樹、渲染布局、繪製,最後呈現給客戶能看到的界面這整個過程。segmentfault

因此瀏覽器的渲染過程主要包括如下幾步:後端

解析HTML生成DOM樹。
解析CSS生成CSSOM規則樹。
將DOM樹與CSSOM規則樹合併在一塊兒生成渲染樹。
遍歷渲染樹開始佈局,計算每一個節點的位置大小信息。
將渲染樹每一個節點繪製到屏幕。

構建DOM樹

當瀏覽器接收到服務器響應來的HTML文檔後,會遍歷文檔節點,生成DOM樹。

須要注意的是,DOM樹的生成過程當中可能會被CSS和JS的加載執行阻塞。渲染阻塞問題下文會講。

構建CSSOM規則樹

瀏覽器解析CSS文件並生成CSS規則樹,每一個CSS文件都被分析成一個StyleSheet對象,每一個對象都包含CSS規則。CSS規則對象包含對應於CSS語法的選擇器和聲明對象以及其餘對象。

渲染阻塞

當瀏覽器遇到一個 script 標記時,DOM 構建將暫停,直至腳本完成執行,而後繼續構建DOM。每次去執行JavaScript腳本都會嚴重地阻塞DOM樹的構建,若是JavaScript腳本還操做了CSSOM,而正好這個CSSOM尚未下載和構建,瀏覽器甚至會延遲腳本執行和構建DOM,直至完成其CSSOM的下載和構建。

因此,script 標籤的位置很重要。實際使用時,能夠遵循下面兩個原則:

CSS 優先:引入順序上,CSS 資源先於 JavaScript 資源。
JS置後:咱們一般把JS代碼放到頁面底部,且JavaScript 應儘可能少影響 DOM 的構建。

當解析html的時候,會把新來的元素插入dom樹裏面,同時去查找css,而後把對應的樣式規則應用到元素上,查找樣式表是按照從右到左的順序去匹配的。

例如: div p {font-size: 16px},會先尋找全部p標籤並判斷它的父標籤是否爲div以後纔會決定要不要採用這個樣式進行渲染)。
因此,咱們平時寫CSS時,儘可能用id和class,千萬不要過渡層疊。

構建渲染樹

經過DOM樹和CSS規則樹咱們即可以構建渲染樹。瀏覽器會先從DOM樹的根節點開始遍歷每一個可見節點。對每一個可見節點,找到其適配的CSS樣式規則並應用。

渲染樹構建完成後,每一個節點都是可見節點而且都含有其內容和對應規則的樣式。這也是渲染樹與DOM樹的最大區別所在。渲染樹是用於顯示,那些不可見的元素固然就不會在這棵樹中出現了,譬如。除此以外,display等於none的也不會被顯示在這棵樹裏頭,可是visibility等於hidden的元素是會顯示在這棵樹裏頭的。

渲染樹佈局

佈局階段會從渲染樹的根節點開始遍歷,而後肯定每一個節點對象在頁面上的確切大小與位置,佈局階段的輸出是一個盒子模型,它會精確地捕獲每一個元素在屏幕內的確切位置與大小。

渲染樹繪製

在繪製階段,遍歷渲染樹,調用渲染器的paint()方法在屏幕上顯示其內容。渲染樹的繪製工做是由瀏覽器的UI後端組件完成的。

reflow與repaint:
根據渲染樹佈局,計算CSS樣式,即每一個節點在頁面中的大小和位置等幾何信息。HTML默認是流式佈局的,CSS和js會打破這種佈局,改變DOM的外觀樣式以及大小和位置。這時就要提到兩個重要概念:replaint和reflow。

replaint:屏幕的一部分重畫,不影響總體佈局,好比某個CSS的背景色變了,但元素的幾何尺寸和位置不變。

reflow:
意味着元件的幾何尺寸變了,咱們須要從新驗證並計算渲染樹。是渲染樹的一部分或所有發生了變化。這就是Reflow,或是Layout。

因此咱們應該儘可能減小reflow和replaint,我想這也是爲何如今不多有用table佈局的緣由之一。

display:none 會觸發 reflow,visibility: hidden屬性並不算是不可見屬性,它的語義是隱藏元素,但元素仍然佔據着佈局空間,它會被渲染成一個空框,因此visibility:hidden 只會觸發 repaint,由於沒有發生位置變化。

有些狀況下,好比修改了元素的樣式,瀏覽器並不會馬上 reflow 或 repaint 一次,而是會把這樣的操做積攢一批,而後作一次 reflow,這又叫異步 reflow 或增量異步 reflow。
有些狀況下,好比 resize 窗口,改變了頁面默認的字體等。對於這些操做,瀏覽器會立刻進行 reflow。

小結

本文咱們就瀏覽器渲染流程逐步瞭解了一遍,相信你們必定都有所新的收穫,若是你們對於瀏覽器渲染流程還有任何疑問,歡迎反饋,咱們共同交流,共同窗習,共同進步。

做者:GavinHsueh,QQ/微信:753391279,專一網站建站、運維及企業web應用開發技術。

參考文獻:
http://taligarsiel.com/Projec...
https://segmentfault.com/a/11...
https://sylvanassun.github.io...
https://www.zybuluo.com/lizla...

相關文章
相關標籤/搜索