html css js各自作用「html css javascript三者關係」

在前面一篇文章:「高頻面試題」瀏覽器從輸入url到頁面展示中間發生了什麼 中,我們有對瀏覽器的渲染流程做了一個概括性的介紹,今天這篇文章我們將深入學習這部分內容。

對於很多前端開發來說,平常做工主要專註於業務開發,對瀏覽器的渲染階段可能不是很了解。實際上這個階段很重要,了解瀏覽器的渲染過程,能讓我們知道我們寫的HTML、CSS、JS代碼是如何被解析,並最終渲染成一個頁面的,在頁面性能優化的時候有相應的解決思路。

我們先來看一個問題:

HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的?

如果你回答不上來,那就往下看吧。

按照渲染的時間順序,渲染過程可以分為下面幾個子階段:構建DOM樹、樣式計算、布局階段、分層、柵格化和合成顯示。

下面詳細看下每個階段都做了哪些事情。

1. 構建DOM樹

HTML文檔描述一個頁面的結構,但是瀏覽器無法直接理解和使用HTML,所以需要通過HTML解析器將HTML轉換成瀏覽器能夠理解的結構——DOM樹。

HTML文檔中所有內容皆為節點,各節點之間有層級關係,彼此相連,構成DOM樹。

構建過程:讀取HTML文檔的位元組(Bytes),將位元組轉換成字元(Chars),依據字元確定標籤(Tokens),將標籤轉換成節點(Nodes),以節點為基準構建DOM樹。參考下圖:

你知道HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的嗎?

打開Chrome的開發者工具,在控制台輸入 document 後回車,就能看到一個完整的DOM樹結構,如下圖所示:

你知道HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的嗎?

在控制台列印出來的DOM結構和HTML內容幾乎一樣,但和HTML不同的是,DOM是保存在內存中的樹狀結構,可以通過JavaScript來查詢或修改其內容。

2. 樣式計算

樣式計算這個階段,是為了計算出DOM節點中每個元素的表現樣式。

2.1 解析CSS

CSS樣式可以通過下面三種方式引入:

  • 通過link引用外部的CSS文件
  • style 標籤內的CSS
  • 元素的style屬性內嵌的CSS

和HTML一樣,瀏覽器無法直接理解純文本的CSS樣式,需要通過CSS解析器將CSS解析成 styleSheets 結構,也就是我們常說的 CSSOM樹。

styleSheets結構同樣具備查詢和修改功能:

document.styleSheets
你知道HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的嗎?

2.2 屬性值標準化

屬性值標準化看字面意思有點不好理解,我們通過下面一個例子來看看什麼是屬性值標準化:

在寫CSS樣式的時候,我們在設置color屬性值的時候,經常會用white、red等,但是這種值瀏覽器的渲染引擎不容易理解,所以需要將所有值轉換成渲染引擎容易理解的、標準化的計算值,這個過程就是屬性值標準化。

white標準化後的值為 rgb(255, 255, 255)

2.3 計算DOM樹中每個節點的樣式

完成樣式的屬性值標準化後,就需要計算每個節點的樣式屬性,這個階段CSS有兩個規則我們需要清楚:

  • 繼承規則:每個DOM節點都包含有父節點的樣式
  • 層疊規則:層疊是CSS的一個基本特徵,是一個定義了如何合併來自多個源的屬性值的演算法。

樣式計算階段是為了計算出DOM節點中每個元素的具體樣式,在計算過程中需要遵守CSS的繼承和層疊兩個規則。

該階段最終輸出的內容是每個DOM節點的樣式,並被保存在 ComputedStyle 的結構中。

3. 布局階段

經過上面的兩個步驟,我們已經拿到了DOM樹和DOM樹中元素的樣式,接下來需要計算DOM樹中可見元素的幾何位置,這個計算過程就是布局。

3.1 創建布局樹

在DOM樹中包含了一些不可見的元素,例如 head 標籤,設置了 display:none 屬性的元素,所以我們需要額外構建一棵只包含可見元素的布局樹。

構建過程:從DOM樹的根節點開始遍歷,將所有可見的節點加到布局樹中,忽略不可見的節點。

你知道HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的嗎?

3.2 布局計算

到這裡我們就有了一棵構建好的布局樹,就可以開始計算布局樹節點的坐標位置了。從根節點開始遍歷,結合上面計算得到的樣式,確定每個節點對象在頁面上的具體大小和位置,將這些信息保存在布局樹中。

布局階段的輸出是一個盒子模型,它會精確地捕獲每個元素在屏幕內的確切位置與大小。

4. 分層

現在我們已經有了布局樹,也知道了每個元素的具體位置信息,但是還不能開始繪製頁面,因為頁面中會有像3D變換、頁面滾動、或者用 z-index 進行z軸排序等複雜效果,為了更方便實現這些效果,渲染引擎還需要為特定的節點生成專用的圖層,並生成一棵對應的圖層樹(LayerTree)。

在Chrome瀏覽器中,我們可以打開開發者工具,選擇 Elements-Layers 標籤,就可以看到頁面的分層情況,如下圖所示:

你知道HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的嗎?

瀏覽器的頁面實際上被分成了很多圖層,這些圖層疊加後合成了最終的頁面。

到這裡,我們構建了兩棵樹:布局樹和圖層樹。下面我們來看下這兩棵樹之間的關係:

你知道HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的嗎?

正常情況下,並不是布局樹的每個節點都包含一個圖層,如果一個節點沒有對應的圖層,那麼這個節點就從屬於父節點的圖層。

那節點要滿足什麼條件才會被提升為一個單獨的圖層?只要滿足下面其中一個條件即可:

  • 擁有層疊上下文屬性的元素會被提升為單獨的一個圖層
  • 需要剪裁(clip)的地方也會被創建為圖層。

5. 圖層繪製

構建好圖層樹之後,渲染引擎就會對圖層樹中的每個圖層進行繪製。

渲染引擎實現圖層繪製,會把一個圖層的繪製拆分成很多小的繪製指令,然後將這些指令按照順序組成一個繪製列表。

6. 柵格化(raster)操作

繪製一個圖層時會生成一個繪製列表,這只是用來記錄繪製順序和繪製指令的列表,實際上繪製操作是由渲染引擎中的合成線程來完成的。

通過下圖來看下渲染主線程和合成線程之間的關係:

你知道HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的嗎?

當圖層的繪製列表準備好後,主線程會把該繪製列表提交給合成線程,合成線程開始工作。

首先合成線程會將圖層劃分為圖塊(tile),圖塊大小通常是 256256 或者 512512。

然後合成線程會按照視口附近的圖塊來優先生成點陣圖,實際生成點陣圖的操作是由柵格化來執行的。所謂柵格化,是指將圖塊轉換為點陣圖。而圖塊是柵格化執行的最小單位。渲染進程維護了一個柵格化的線程池,所有的圖塊柵格化都是在線程池內執行的,運行方式如下圖所示:

你知道HTML、CSS、JS文件在瀏覽器中是如何轉化成頁面的嗎?

7. 合成和顯示

一旦所有圖塊都被光柵化,合成線程就會生成一個繪製圖塊的命令——「DrawQuad」,然後將該命令提交給瀏覽器進程。

瀏覽器進程裡面有一個名字叫做 viz 的組件,用來接收合成線程發過來的 DrawQuad 命令,然後根據命令執行。 DrawQuad 命令,將其頁面內容繪製到內存中,最後再將內存顯示在屏幕上。

多年開發老碼農福利贈送:網頁製作,網站開發,web前端開發,從最零基礎開始的的HTML+CSS+JavaScript。jQuery,Vue、React、Ajax,node,angular框架等到移動端小程序項目實戰【視頻+工具+電子書+系統路線圖】都有整理,需要的夥伴可以私信我,發送「前端」等3秒後就可以獲取領取地址,送給每一位對編程感興趣的小夥伴

8. 總結

一個完整的渲染流程可以總結如下:

  • 1、渲染進程將HTML內容轉換為瀏覽器能夠讀懂的DOM樹結構。
  • 2、渲染引擎將CSS樣式錶轉化為瀏覽器可以理解的styleSheets,計算出DOM節點的樣式。
  • 3、創建布局樹,並計算所需元素的布局信息。
  • 4、對布局樹進行分層,並生成分層樹。
  • 5、為每個圖層生成繪製列表,並將其提交到合成線程。
  • 6、合成線程將圖層分圖塊,並柵格化將圖塊轉換成點陣圖。
  • 7、合成線程發送繪製圖塊命令給瀏覽器進程。瀏覽器進程根據指令生成頁面,並顯示到顯示器上。

渲染過程中還有兩個我們經常聽到的概念:重排和重繪。在這篇文章中就不細說了,下一篇文章再詳細介紹。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/275239.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-17 14:20
下一篇 2024-12-17 14:20

相關推薦

發表回復

登錄後才能評論