渲染引擎 & 頁面渲染流程 & 阻塞

文檔對象模型(Document Object Model,簡稱DOM)javascript

瀏覽器渲染引擎css

  • 一個渲染引擎 主要模塊:
  • HTML 解析器

解釋 HTML 文檔的解析器,將 HTML 文本 解析成 DOM 樹html

  • css 解析器

級聯樣式的解析器,爲 DOM 中的各個元素計算出樣式信息,爲佈局提升基礎設施java

  • javascript 引擎

使用 Javascript 代碼能夠修改網頁的內容,也能修改 css 的信息webpack

javascript 引擎可以解釋 javascript 代碼,並經過 DOM 接口和 CSSOM 接口來修改網頁內容和樣式信息,從而改變渲染的結果。web

  • layout 佈局模塊

在 DOM 建立以後,Webkit 須要將其中的元素對象一樣式信息結合起來,gulp

計算他們的大小位置等佈局信息,造成一個能表達這全部信息的內部表示模型瀏覽器

  • 繪圖模塊

使用 圖形庫 將佈局計算後的各個網頁的節點 繪製成 圖像結果網絡

  • 瀏覽器渲染頁面的整個過程,瀏覽器會從上至下解析文檔:

以上這些模塊依賴不少其餘的基礎模塊,包括要使用到網絡 存儲 2D/3D圖像 音頻視頻解碼器 和 圖片解碼器。異步

因此渲染引擎中還會包括如何使用這些依賴模塊的部分。

1. 碰見 HTML 標記

調用 HTML 解析器解析爲對應的 token (一個 token 就是一個標籤文本的序列化)

並構建 DOM 樹(就是一塊內存,保存着 tokens,創建它們之間的關係)

2. 碰見 style/link 標記 調用 css 解析器 處理 CSS 標記並構建 內部表示結構 CSSOM 樹

CSS 解析器工做完成以後,在 DOM 樹上附加解釋後的樣式信息,這就是 RenderObject 樹

RenderObject 在建立的同時,Webkit 會根據網頁的結構建立 RenderLayer,同時構建一個繪圖上下文

根據 繪圖上下文 生成最終的圖像(這一過程須要依賴圖形庫)

3. 碰見 script 標記 調用 javascript 解析器 處理 script 標記,綁定事件、修改 DOM 樹 / CSSOM樹 等

4. 將 DOM 樹 與 CSSOM 樹 再次合併成一個渲染樹 Render 樹

5. 根據 渲染樹 來佈局,以計算每一個節點的幾何信息____重排

6. 將各個節點繪製到屏幕上____重繪

  • 上面介紹的是一個完整的渲染過程

但現代網頁不少都是動態的,這意味着在渲染完成以後,

因爲網頁的動畫或者用戶的交互,瀏覽器其實一直在不停地重複執行渲染過程。(重繪重排)

以上的數字表示的是基本順序,這不是嚴格一致的,這個過程可能重複也可能交叉

  • 網頁在加載和渲染過程會觸發 "DOMContentLoaded" 和 "load" 事件

----> 分別在 DOM 樹解析完成後,觸發 "DOMContentLoaded"

----> DOM 樹構建而且網頁全部依賴資源都加載完成以後發生,觸發 "load"

  • 實際測試

瀏覽器加載資源是異步的

用 <style> 內部樣式表 寫 css,是由 Parse HTML 異步解析的。

一張圖片分屢次解析,其中 Parse HTML 這麼快,體現了其異步執行,只是開啓了一個任務,讓它本身去請求資源並解析

  • css 阻塞 ---- 樣式寫在外部文件,在 index.css 中 link 導入

經過 link 進來的樣式 是同步解析的,由 Parse Stylesheet 進行解析

正由於是同步解析,因此 css 解析器 會阻塞頁面的渲染,從而避免了閃屏

這也是爲何推薦使用 <style link='index.css'> 引入外部樣式表

  • 阻塞
  • css 阻塞
  • <style> 標籤中的樣式

1. 由 html 解析器進行解析

2. 不阻塞瀏覽器渲染

3. 不阻塞 DOM 解析

  • <link src='index.css'> 引入的外部 css 樣式 (推薦使用 <link> 方式引入外部 css,能夠避免閃屏現象)

1. 由 CSS 解析器進行解析

2. 會阻塞瀏覽器頁面渲染(緣由:避免閃屏)

<link rel="stylesheet" href="css/my-sleep-3000-commen.css" />

3. 不阻塞 DOM 結構的解析

由於 DOM 解析 和 CSS 解析是兩個並行的進程

瀏覽器解析 DOM 生成 DOM Tree,解析 CSS 生成 CSS Tree

最終組成 render Tree,再渲染頁面,DOM 的解析,和 CSS的解析並行的。

4. 會阻塞 js 的執行(但不會阻塞 js 等資源的加載)

腳本在文檔解析階段會請求樣式信息,若是 css 尚未徹底加載解析完,腳本可能得到錯誤的回覆

  • FireFox 會在樣式表加載解析過程當中,禁止全部腳本
  • 對於 WebKit 而言,僅當腳本嘗試訪問樣式屬性可能會獲得錯誤的回覆時,禁止腳本的執行

優化方案:  (儘量快的提升 css 加載速度)

  • 使用 CDN 加速
  • 對 css 進行壓縮(用打包工具,好比 webpack, gulp 等,也能夠經過開啓 gzip 壓縮)
  • 減小 http 請求數,將多個 css 文件合併
  • js 阻塞

會阻塞 DOM 解析

由於 js 可能會修改 DOM 樹

會阻塞 頁面的渲染

由於 js 代碼可能會修改 DOM 樹 / CSSOM 樹 的結構

js 會順序執行,阻塞後續 js 邏輯的執行 (不阻塞 js 等其餘資源的加載)

維護依賴關係

css 的解析 和 js 的執行 是互斥的 ( css 解析的時候 js 中止執行,js 執行的時候 css 中止解析)

預解析

WebKit 和 FireFox 都進行了這項優化。

在執行 js 腳本時,其餘線程會解析文檔的其他部分 (只是檢查,不影響原結構),找出並加載須要網絡加載的其餘資源

使得這些資源在並行鏈接上加載,從而提升整體速度

預解析器 不會修改 DOM 樹,而是將這件事交給 主解析器 處理

預解析器 只會解析外部資源的引用(例如外部腳本、樣式、圖片)

提早發送請求,提早解析外部資源內容

相關文章
相關標籤/搜索