1. 程式人生 > >關於瀏覽器的頁面渲染

關於瀏覽器的頁面渲染

關於瀏覽器渲染

 先來看一張webkit引擎的大致渲染流程:
u=2178105265,11552355&fm=173&s=C981ED120360750B1CC181D60200C0F2&w=624&h=289&img.jpg

頁面渲染可分為下面幾個步驟:

  1. 處理HTML標記並構建DOM樹
  2. 處理CSS標記並構件CSSOM樹
  3. 將DOM與CSSOM樹合併成一個渲染樹
  4. 根據渲染樹來佈局,計算每個節點的確切大小和位置
  5. 將各節點繪製到螢幕上

 關於瀏覽器渲染,一個重要概念就是關鍵渲染路徑

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



阻塞渲染:

 html的解析遇到script標籤會停止DOM樹的解析並開始下載執行js。因為js是會阻塞html解析的,是阻塞資源。其原因在於js可能會改變html現有結構。例如有的節點是用js動態構建的,在這種情況下就會停止dom樹的構建開始下載解析js。指令碼在文件的何處插入,就在何處執行。當 HTML 解析器遇到一個 script 標記時,它會暫停構建 DOM,將控制權移交給 JavaScript 引擎;等 JavaScript 引擎執行完畢,瀏覽器會從中斷的地方恢復 DOM 構建。而因此就會推遲頁面首繪的時間。可以在首繪不需要js的情況下用async和defer實現非同步載入。這樣js就不會阻塞html的解析了。
 css的載入不會導致DOM解析和構建,但是會影響到js指令碼的執行;因為js指令碼不僅可以讀取修改到dom,也可以讀取修改到cssom。故在js指令碼執行前,browser必須保證到css檔案完全載入並解析完成,即cssom樹完全構建好。這就導致了js執行的延遲,也因此導致html解析和渲染延遲。 (這就是css阻塞js執行,阻塞渲染的根本原因) 所以在在引入順序上,一般css資源的引入要先於js指令碼的引入。



重繪和重排:

 重繪 repaint:螢幕的一部分重畫,不影響整體佈局,比如某個CSS的背景色變了,但元素的幾何尺寸和位置不變。
 重排 reflow:意味著元件的幾何資訊變了,需要重新驗證並計算渲染樹。是渲染樹的一部分或全部發生了變化。 有以下這些情況可能觸發:

  • DOM操作(對元素的增刪改,順序變化等)
  • CSS屬性的更改或重新計算
  • 增刪樣式表的內容
  • 修改class屬性
  • 瀏覽器視窗變化(滾動或縮放)
  • 偽類樣式啟用(:hover等)

重繪和重排需要重新計算整個渲染樹,比較耗時;因此關於頁面優化很多許多本質上都是為了減少重繪和重排的次數。


 注意:

display:none 會觸發 reflow,visibility: hidden屬性並不算是不可見屬性,它的語義是隱藏元素,但元素仍然佔據著佈局空間,它會被渲染成一個空框,所以visibility:hidden 只會觸發 repaint。