渲染流程與合成 | Rendering Pipeline & Compositing | Advance Web Development Quiz | #2
此文章是 FrontendMaster 課程的筆記
以下敘述何者正確?
- [ ] 渲染樹 (render tree) 包含了 DOM 和 CSSOM 結合後的所有元素
- [ ] 版面配置(layout)流程會為渲染樹中的視覺元素分配顏色與圖像
- [ ] 合成(compositing)是根據元素的 z-index 將圖層分離,然後再組合形成最終顯示在螢幕上的影像的過程
- [ ] 合成過程發生在合成執行緒(compositor thread)上
- [ ] 不可見的元素(例如 display: none)不屬於 DOM 樹的一部分
原文
- [ ] The render tree contains all elements from the DOM and CSSOM combined
- [ ] The layout process assigns colors and images to the visual elements in the render tree
- [ ] Compositing is the process of separating layers based on elements z-index, which are then combined to form the final image displayed on the screen
- [ ] The compositing process happens on the compositor thread
- [ ] Elements that aren't visible on the page, for example display: none, aren't part of the DOM tree
答案在最下面
這題很明顯是在考整個渲染的流程,而我是一點都不記得了,馬上來回憶一下
渲染流程 Rendering Pipeline
瀏覽器渲染流程:把 HTML、CSS、JS 這些文字檔,逐步轉成一棵棵樹結構,算出每個元素的位置與樣式,最後再畫成螢幕上的像素。 大致上是以下幾個階段「請求 → 解析 → DOM 樹 & CSSOM → 樣式與渲染樹 → 佈局 → 繪製」,以上為最初的步驟,但後續可能會被 JavaScript、CSS 或 Web Animations API 主動觸發重繪/回流。
課程影片是從解析 render tree 開始說明,但我多查了前面的請求階段
0. 請求
在瀏覽器取得資料前,還有以下步驟要依序完成:
導航 (Navigate):找到正確的伺服器
- 瀏覽器要先搞清楚「這個網域在哪台機器上?」
- 包含這些步驟:DNS 查詢 → TCP/TLS 握手 → 送出 HTTP GET
- DNS 查詢:如果是第一次請求就需要先找到 DNS 伺服器的 IP,之後就會從快取拿(如果頁面裡面有多種還沒有存快取的網域,這個步驟會執行多次去一一記錄每個網域的 DNS)
- TCP/TLS 握手:建立連線的協議。兩種協議皆由瀏覽器端先發起
- TCP:建立連線,會有三次的握手。
- TLS:如果是 https 的網站,就必須做這個協議,用來確認加密方式確保資料的安全性,進行五次握手
傳輸:瀏覽器請求 HTML/資源,並開始接收伺服器傳送過來的資料
- 透過 TCP 的協議把資料切分成很多小塊的封包傳遞資料,資料傳達之後才會重新組合起來,這樣子的做法可以讓資料如果傳輸錯誤時,只需要重新傳遞一小包資料,而不需要整個重新傳遞,另外也不需要
1. 解析 Parse HTML & Parse Stylesheet
瀏覽器一收到 HTML 就會開始解析(不會等到整個文件送達),此時會逐步建構 DOM 樹與 CSSOM (CSS Object Model)
DOM 樹
- 瀏覽器透過 HTML 解析器來把 HTML 轉換成 DOM (Document Object Model)
- 以
<html>作為樹的根節點,把 HTML 上的標籤、屬性等等的資訊一層層的建構出 DOM 樹,這個樹可以反應各個節點之間的關係與層次 - 節點越多,就越花費時間
- 解析器在過程中如果發現非阻塞的資源,就會請求這些資源並繼續解析,反之,遇到會阻塞的資源則會停止解析
- 在主執行緒執行此任務
CSSOM 樹
- 建構 CSSOM 樹的過程跟 DOM 樹差不多,把所有的 CSS(包含
<style>、inline style、<link rel="stylesheet" />)都建構成一層層的節點樹 - 在主執行緒執行此任務
- 建構 CSSOM 樹的過程跟 DOM 樹差不多,把所有的 CSS(包含
2. 樣式與渲染樹 Style & Render tree
有時候也會稱這個階段為重新計算樣式 (Recalculate Style) 或渲染樹更新 (Render Tree Update)
建立渲染樹會有以下步驟:
- 根據 DOM 遞迴地尋找要顯示的元素
- 建構/更新 指向 DOM 節點的渲染樹節點
- 為該 DOM 節點推導 ComputedStyels,並與 DOM 節點和渲染樹節點關聯
渲染樹 Render Tree
把 DOM 與 CSSOM 合併成一個獨立的渲染樹,這個渲染樹的每一個節點包含內容與樣式。
此階段會排除不顯示的元素(例:帶有display:none的節點),不過 visibility: hidden 這類的節點仍然會在渲染樹中,因為他們會佔用空間。
計算樣式 ComputedStyle
把 CSS 宣告配對到 DOM 節點上,會考慮到 DOM 節點的選擇器、CSS 的權重與 CSSOM 中彙整的規則,確立每個節點上的 CSS 規則。
3. 佈局 Layout
這個階段會依照渲染樹上所有的 CSS 宣告來計算每個節點的尺寸、位置、換行、position、overflow、z-index
第一次進行到這個階段時,叫做 layout,當之後 DOM 結構或影響排版的 CSS 屬性改變時,造成部分或全部的重新計算,這個時候則叫做 reflow。
Layout 的過程可能非常昂貴,因此瀏覽器會大量快取以避免不必要的重新計算 Layout
4. 繪製 Paint
此階段會依據不同的圖層 (Layer) 去繪製畫面,把每個節點繪製實際像素到畫面上,包括文字、顏色、邊框、陰影。 當元素被提升到獨立圖層,瀏覽器可以只更新部分圖層,而不需要更新全部圖層,可以藉此來提升渲染效能
- 圖層可能因為以下方式把元素提升成獨立的圖層:
- CSS 屬性:
position: fixed、position: stikcy- animations
will-change、transform、opacityfilter、clip-path、clip
- animation 或 filters 的複雜效果
- 硬體加速的元素:
<video>、<canvas>
- CSS 屬性:
圖層可以直接影響效能
- 獨立重繪:分隔的圖層元素重新繪製不會影響到其他圖層,對某個圖層的變更不需要重新渲染整個頁面
- 記憶體使用:圖層可以透過獨立執行緒 (Compositor Thread)獨立進行更新,雖然可以提升效能,但太多層反而會增加記憶體消耗,所以過度使用反而會出現反效果
最後當有不同的圖層重疊時,會用正確的順序進行合成 (composite) 繪製到畫面上。
圖層不是用來排序視覺元素,是底層的 GPU/光柵化的流程,並不是 CSS 樣式,所以與 z-index 無關
答案
- [ ] 渲染樹 (render tree) 包含了 DOM 和 CSSOM 結合後的所有元素
- [ ] 版面配置(layout)流程會為渲染樹中的視覺元素分配顏色與圖像
- [ ] 合成(compositing)是根據元素的 z-index 將圖層分離,然後再組合形成最終顯示在螢幕上的影像的過程
- [x] 合成過程發生在合成執行緒(compositor thread)上
- [ ] 不可見的元素(例如 display: none)不屬於 DOM 樹的一部分
原文
- [ ] The render tree contains all elements from the DOM and CSSOM combined
- [ ] The layout process assigns colors and images to the visual elements in the render tree
- [ ] Compositing is the process of separating layers based on elements z-index, which are then combined to form the final image displayed on the screen
- [x] The compositing process happens on the compositor thread
- [ ] Elements that aren't visible on the page, for example display: none, aren't part of the DOM tree
太多內容可以查了...讀得越多懂的越少
References
轉譯效能 "web.dev"渲染頁面:瀏覽器的工作原理 "MDN"Layers and Compositing "Web Performance Tips"
