回顧前一部分
在文章瀏覽器渲染 pipeline 第一部分中,我們已經回顧了瀏覽器渲染 pipeline part 1,並了解到瀏覽器會解析 HTML 和 CSS 並建立 DOM 樹和 CSSOM 樹,這背後的主要角色是渲染引擎。
不同類型的渲染引擎
不同的瀏覽器使用不同的渲染引擎,以下是一些例子:
- IE:Trident
- Firefox:Gecko
- Safari:WebKit
- Chrome 和 Opera:Blink(基於 WebKit)
主要流程
在從網路層獲取請求文件的內容後,渲染引擎的基本流程如下:
解析階段
在這個階段,渲染引擎會解析 HTML 和 CSS,並建立 DOM 樹和 CSSOM 樹。 同時,JavaScript 引擎會執行指令碼,每個指令碼都會在單一執行緒中執行,並一個接一個地推入呼叫堆疊,執行順序基於 LIFO(後進先出)。如果觸發了 DOM 事件或計時器事件,它會被推入事件佇列。請記住,呼叫堆疊上的執行優先順序始終高於事件佇列,您可以參考 JavaScript 事件循環獲取更多詳細資訊。
渲染階段
在這個階段,DOM 樹和 CSSOM 樹會組合成渲染樹,然後瀏覽器會進行渲染樹的佈局和繪製,最後合成最終圖像並顯示在螢幕上。讓我們深入了解每個階段。
佈局樹
在這個階段,瀏覽器會做幾件事:
- 計算每個節點的位置和大小。
- 處理盒模型、定位和浮動。
- 然後建立佈局樹。
繪製階段
在這個階段,瀏覽器會:
- 將佈局轉換為實際像素。
- 處理繪製順序,例如 z-index。
- 處理顏色、邊框或陰影等。
- 在螢幕上繪製內容。
合成階段
在這個階段,瀏覽器會將不同的圖層合成為單一圖像,並顯示在螢幕上。
回流和重繪
某些操作會觸發回流或重繪,讓我們回顧一下:
回流
回流是重新計算元素佈局的過程,當元素的大小或位置改變時會觸發,例如我們新增元素、更改元素樣式或調整視窗大小等。這是一種非常耗費資源的操作,我們應該盡可能避免。
element.style.width = "100px";
element.style.height = "100px";
element.style.left = "100px";上述程式碼展示了一個簡單的回流,因為我們多次更改元素的樣式。更好的做法是使用 element.cssText 來一次性更改元素的樣式,像這樣:
// Batches changes
element.cssText = "width: 100px; height: 100px; left: 100px;";🧐 嗯...RWD(響應式網頁設計)會觸發回流嗎?
響應式設計
初始載入時的媒體查詢會靜態套用樣式,所以它們不會導致額外的回流,但當視窗大小調整時,瀏覽器需要重新計算元素的佈局,所以會觸發回流。讓我們看一個例子:
<style>
@media (min-width: 768px) {
.container {
width: 750px;
}
}
@media (min-width: 1200px) {
.container {
width: 1170px;
}
</style>請記住,如果 CSS 值更改了佈局,例如 width、height、left、top、margin、padding 等,會觸發回流;如果只更改了視覺屬性,例如 color、border、shadow 等,會觸發重繪。
重繪
當只有視覺屬性改變時觸發,例如顏色、邊框或陰影等,這需要重新執行繪製和合成階段,比回流消耗更少的資源。
結論
- 在網路層,瀏覽器會獲取請求文件的內容。
- 在解析階段,瀏覽器會解析 HTML 和 CSS,並建立 DOM 樹和 CSSOM 樹。
- 在渲染階段,瀏覽器會對渲染樹進行佈局和繪製,最後合成最終圖像並顯示在螢幕上。
- 某些操作會觸發回流或重繪,我們應該盡可能避免它們。
- 影響佈局的 CSS 值更改會觸發回流。
- 不影響佈局的 CSS 值更改會觸發重繪。
- 回流比重繪消耗更多資源。