1. 程序架構
1.1 程序和線程
- 當啟動一個程式時,作業系統會為該程式配置設定記憶體,用來存放代碼、運作過程中的資料,這樣的運作環境叫做程序
- 一個程序可以啟動和管理多個線程,線程之間可以共享進行資料,任何一個線程出錯都可能會導緻程序崩潰
1.2 Chrome 的程序架構
- 浏覽器主程序 負責界面顯示、使用者互動和子程序管理
- 渲染程序 排版引擎和 V8 引擎運作在該程序中,負責把 HTML、CSS 和 JavaScript 轉變成網頁
- 網絡程序 用來加載網絡資源的
- GPU 程序 用來實作 CSS3 和 3D 效果
2. 加載 HTML
- (1)主程序接收使用者輸入的 URL
- (2)主程序把該 URL 轉發給網絡程序
- (3)在網絡程序中發起 URL 請求
- (4)網絡程序接收到響應頭資料并轉發給主程序
- (5)主程序發送送出導航消息到渲染程序
- (6)渲染程序開始從網絡程序接收 HTML 資料
- (7)HTML 接收接受完畢後通知主程序确認導航
- (8)渲染程序開始 HTML 解析和加載子資源
- (9)HTML 解析完畢和加載子資源頁面加載完成後會通知主程序頁面加載完成
3. 渲染流水線
- (1) 渲染程序把 HTML 轉變為 DOM 樹型結構
- (2) 渲染程序把 CSS 文本轉為浏覽器中的stylesheet
- (3) 通過 stylesheet 計算出 DOM 節點的樣式
- (4) 根據 DOM 樹建立布局樹
- (5) 并計算各個元素的布局資訊
- (6) 根據布局樹生成分層樹
- (7) 根據分層樹進行生成繪制步驟
- (8) 把繪制步驟交給渲染程序中的合成線程進行合成
- (9) 合成線程将圖層分成圖塊(tile)
- (10) 合成線程會把分好的圖塊發給栅格化線程池,栅格化線程會把圖檔(tile)轉化為位圖
- (11) 而其實栅格化線程在工作的時候會把栅格化的工作交給 GPU 程序來完成,最終生成的位圖就儲存在了GPU記憶體中
- (12) 當所有的圖塊都光栅化之後合成線程會發送繪制圖塊的指令給浏覽器主程序
- (13) 浏覽器主程序然後會從 GPU 記憶體中取出位圖顯示到頁面上
3.1 HTML 轉 DOM 樹
- 浏覽器中的 HTML 解析器可以把 HTML 字元串轉換成 DOM 結構
- HTML 解析器邊接收網絡資料邊解析 HTML
- 解析 DOMHTML 字元串轉 TokenToken 棧用來維護節點之間的父子關系,Token 會依次壓入棧中如果是開始标簽,把 Token 壓入棧中并且建立新的 DOM 節點并添加到父節點的 children 中如果是文本 Token,則把文本節點添加到棧頂元素的 children 中,文本 Token 不需要入棧如果是結束标簽,此開始标簽出棧
3.2 CSS 轉 stylesheet
- 渲染程序把 CSS 文本轉為浏覽器中的stylesheet
- CSS 來源可能有 link 标簽、style 标簽和 style 行内樣式
- 渲染引擎會把 CSS 轉換為document.styleSheets
3.3 計算出 DOM 節點的樣式
- 根據 CSS 的繼承和層疊規則計算 DOM 節點的樣式
- DOM 節點的樣式儲存在了ComputedStyle中
3.4 建立布局樹
- 建立一棵隻包含可見元素的布局樹
3.5 計算布局
- 計算各個元素的布局
3.6 生成分層樹
- 根據布局樹生成分層樹
- 渲染引擎需要為某些節點生成單獨的圖層,并組合成圖層樹z-index絕對定位和固定定位濾鏡透明裁剪
- 這些圖層合成最終的頁面
3.6 繪制
- 根據分層樹進行生成繪制步驟複合圖層
- 每個圖層會拆分成多個繪制指令,這些指令組合在一起成為繪制清單
3.7 合成線程
- 合成線程将圖層分成圖塊(tile)
- 合成線程會把分好的圖塊發給栅格化線程池,栅格化線程會把圖檔(tile)轉化為位圖
- 而其實栅格化線程在工作的時候會把栅格化的工作交給 GPU 程序來完成,最終生成的位圖就儲存在了GPU記憶體中
- 當所有的圖塊都光栅化之後合成線程會發送繪制圖塊的指令給浏覽器主程序
- 浏覽器主程序然後會從 GPU 記憶體中取出位圖顯示到頁面上
- 合成線程
3.7.1 圖塊
- 圖塊渲染也稱基于瓦片渲染或基于小方塊渲染
- 它是一種通過規則的網格細分計算機圖形圖像并分别渲染圖塊(tile)各部分的過程
3.7.2 栅格化
- 栅格化是将矢量圖形格式表示的圖像轉換成位圖以用于顯示器輸出的過程
- 栅格即像素
- 栅格化即将矢量圖形轉化為位圖(栅格圖像)
3.8 資源加載
- CSS 加載不會影響 DOM 解析
- CSS 加載不會阻塞 JS 加載,但是會阻塞 JS 執行
- JS 會依賴 CSS 加載,JS 會阻塞 DOM 解析