瞭解關鍵路徑

關鍵轉譯路徑是指網頁開始在瀏覽器中轉譯前,所需的所有步驟。為了轉譯網頁,瀏覽器需要 HTML 文件本身,以及轉譯該文件所需的所有重要資源。

前一個 HTML 一般效能考量模組已說明如何將 HTML 文件傳送至瀏覽器。不過,在本單元中,我們會進一步探討瀏覽器在下載 HTML 文件,為了轉譯網頁而執行的動作。

漸進式算繪

網路的本質就是分散式,與安裝後再使用的原生應用程式不同,瀏覽器無法依賴網站提供所有轉譯網頁所需的資源。因此,瀏覽器非常擅長逐步算繪網頁。原生應用程式通常會經歷安裝階段,然後是執行階段。不過,對於網頁和網路應用程式而言,這兩個階段之間的界線就沒有那麼明顯,瀏覽器的設計也特別考量到這點。

一旦瀏覽器有資源可算繪網頁,通常就會開始算繪。因此,選擇算繪時間就成了關鍵:何時算繪太早?

如果瀏覽器在只載入部分 HTML 時盡快轉譯,但尚未載入任何 CSS 或必要的 JavaScript,則網頁會暫時看起來有問題,並在最終轉譯時大幅變更。這比初始顯示空白畫面更糟糕,因為瀏覽器必須等到有更多資源,才能提供初始轉譯功能,提供更優質的使用者體驗。

另一方面,如果瀏覽器等待所有資源可用,而不是進行任何順序轉譯,使用者就必須等待很長一段時間;如果網頁在更早的時間點就能使用,則通常不必等待這麼久。

瀏覽器需要知道應等待的最小資源數量,以免呈現明顯中斷的體驗。另一方面,瀏覽器也不應讓使用者等待過久,才能顯示內容。瀏覽器在執行初始轉譯作業前採取的步驟順序,稱為「重要轉譯路徑」

瞭解關鍵轉譯路徑有助於改善網頁效能,因為這樣可確保您不會不必要地阻斷初始網頁轉譯作業。不過,請務必從關鍵算繪路徑中移除初始算繪所需的資源,以免算繪過早發生。

(關鍵) 算繪路徑

轉譯路徑包含下列步驟:

  • 從 HTML 建構文件物件模型 (DOM)。
  • 從 CSS 建構 CSS 物件模型 (CSSOM)。
  • 套用任何會變更 DOM 或 CSSOM 的 JavaScript。
  • 從 DOM 和 CSSOM 建構轉譯樹狀結構。
  • 在頁面上執行樣式和版面配置作業,瞭解哪些元素適合放在哪裡。
  • 在記憶體中繪製元素的像素。
  • 如果有重疊的像素,則合成這些像素。
  • 將所有產生的像素實際繪製到螢幕上。
從 HTML 和 CSS 到像素顯示的轉譯程序。
如上方清單所述,算繪程序。

只有在完成所有步驟後,使用者才能在螢幕上看到內容。

這個轉譯程序會重複多次。初始轉譯作業會叫用這個程序,但隨著影響網頁轉譯作業的資源越來越多,瀏覽器就會重新執行這個程序 (或部分程序),以更新使用者看到的內容。關鍵轉譯路徑會著重於先前為初始轉譯所定義的程序,並取決於所需的關鍵資源。

關鍵算繪路徑包含哪些資源?

瀏覽器必須等待部分重要資源下載完畢,才能完成初始轉譯。這些資源包括:

  • HTML 的一部分。
  • <head> 元素中的轉譯封鎖 CSS。
  • <head> 元素中的轉譯封鎖 JavaScript。

重點是,瀏覽器會以串流方式處理 HTML。瀏覽器只要取得網頁 HTML 的任何部分,就會開始處理。接著,瀏覽器可以 (而且通常會) 在收到網頁的 HTML 其餘部分之前,決定是否要算繪該圖片。

請注意,在初始轉譯作業中,瀏覽器通常不會等待下列項目:

  • 所有 HTML。
  • 字型。
  • 圖片。
  • <head> 元素外部的非轉譯阻斷 JavaScript (例如放在 HTML 結尾的 <script> 元素)。
  • <head> 元素外部的非轉譯阻斷 CSS,或是含有 media 屬性值的 CSS,但該值不適用於目前的可視區域。

瀏覽器通常會將字型和圖片視為要在後續網頁重新轉譯期間填入的內容,因此不需要延遲初始轉譯作業。不過,這可能表示在初始轉譯作業中,會留下空白區域,因為文字會在字型或圖片可用前隱藏。更糟的是,如果未為特定類型的內容保留足夠的空間 (尤其是在 HTML 中未提供圖片尺寸時),網頁的版面配置可能會在稍後載入這類內容時移位。使用者體驗的這項層面可透過累積版面配置位移 (CLS) 指標進行評估。

<head> 元素是處理關鍵算繪路徑的關鍵。因此,下一節會詳細說明。最佳化 <head> 元素的內容是提升網頁效能的關鍵。不過,如要瞭解關鍵算繪路徑,您只需要知道 <head> 元素包含網頁及其資源的中繼資料,但沒有使用者可見的實際內容。可見內容包含在 <head> 元素後面的 <body> 元素中。瀏覽器必須同時具備要轉譯的內容和轉譯方式的中繼資料,才能轉譯任何內容。

不過,並非所有 <head> 元素參照的資源,都對初始網頁算繪作業而言是絕對必要的,因此瀏覽器只會等待必要的資源。如要找出在關鍵算繪路徑中的資源,您必須瞭解會造成轉譯阻斷和剖析阻斷的 CSS 和 JavaScript。

會妨礙顯示的資源

部分資源會被視為非常重要,因此瀏覽器會暫停網頁轉譯,直到處理完這些資源為止。根據預設,CSS 會歸入這個類別。

瀏覽器看到 CSS 時,無論是 <style> 元素中的內嵌 CSS,還是 <link rel=stylesheet href="..."> 元素指定的外部參照資源,都會在下載及處理 CSS 後,避免算繪更多內容。

資源阻擋轉譯,不一定會阻止瀏覽器執行其他作業。瀏覽器會盡可能提高效率,因此當瀏覽器發現需要下載 CSS 資源時,會要求下載並暫停轉譯,但仍會繼續處理 HTML 的其餘部分,並在同時尋找其他可執行的工作。

會妨礙顯示的資源 (例如 CSS),用於在發現時阻擋所有網頁的顯示作業。也就是說,某些 CSS 是否會造成轉譯阻斷,取決於瀏覽器是否已發現該 CSS。部分瀏覽器 (最初是 Firefox,現在Chrome 也加入) 只會封鎖位於轉譯阻斷資源下方的內容轉譯。也就是說,對於關鍵的算繪阻斷路徑,我們通常會關注 <head> 中的算繪阻斷資源,因為這些資源會有效阻斷整個網頁的算繪作業。

近期的創新功能是 blocking=render 屬性已新增至 Chrome 105。這可讓開發人員明確將 <link><script><style> 元素標示為轉譯阻斷,直到元素處理完畢為止,但仍允許剖析器在同時繼續處理文件。

剖析器封鎖資源

解析器封鎖資源是指會阻止瀏覽器繼續解析 HTML,進而阻止瀏覽器尋找其他工作。根據預設,JavaScript 會阻斷剖析器 (除非特別標示為「非同步」或「延遲」),因為 JavaScript 可以在執行時變更 DOM 或 CSSOM。因此,瀏覽器必須先瞭解所要求的 JavaScript 對網頁 HTML 的完整影響,才能繼續處理其他資源。因此,同步 JavaScript 會封鎖剖析器。

剖析器阻斷資源也會有效阻斷轉譯。由於解析器必須完全處理解析阻斷資源,才能繼續處理後續資源,因此無法存取及轉譯後續資源。瀏覽器可以在等待期間算繪所有目前收到的 HTML,但在關鍵算繪路徑方面,<head> 中的任何解析器阻斷資源,實際上都會導致所有網頁內容無法算繪。

阻斷剖析器可能會導致效能成本大幅增加,遠遠超過阻斷轉譯的成本。因此,瀏覽器會在主要 HTML 剖析器遭到封鎖時,使用稱為「預先載入掃描器」的次要 HTML 剖析器,下載即將到來的資源,藉此降低這項成本。雖然這不如實際剖析 HTML 來得好,但至少可讓瀏覽器中的網路功能在遭到封鎖的剖析器前運作,也就是說,日後不太可能再次遭到封鎖。

找出阻斷資源

許多效能稽核工具會找出會阻斷轉譯和剖析的資源。WebPageTest 會在資源網址左側以橘色圓圈標示會造成轉譯阻斷的資源:

WebPageTest 產生的網路階層圖表。在資源網址左側,會以橘色圓圈標示解析器阻斷資源,而開始算繪時間則以實心深綠線標示。
WebPageTest 產生的網路瀑布圖表。

所有轉譯阻斷資源都必須下載及處理,才能開始轉譯,這點可從瀑布圖中的實心深綠色線看出。

Lighthouse 也會以較不明顯的方式標示會造成轉譯阻斷的資源,但只有在資源實際延遲網頁轉譯時才會標示。這有助於避免在盡量減少轉譯阻斷的情況下,出現偽陽性。透過 Lighthouse 執行與上一個 WebPageTest 圖表相同的網頁網址,只會將其中一個樣式表單識別為轉譯阻斷資源。

Lighthouse 的稽核項目,用於排除會妨礙顯示的資源。稽核結果會顯示封鎖轉譯的資源,以及封鎖的時間長度。
Lighthouse 稽核項目,用於排除會妨礙顯示的資源。

最佳化重要算繪路徑

如要改善關鍵運算路徑,請按照上一個單元詳細說明的做法,縮短接收 HTML 的時間 (以 Time to First Byte (TTFB) 指標表示),並減少阻斷運算的資源影響。這些概念會在後續單元中探討。

關鍵的含內容算繪路徑

長久以來,關鍵算繪路徑一直只著重於初始算繪。不過,現在有越來越多以使用者為重點的網路效能指標,因此有人質疑關鍵轉譯路徑的終點應是第一個顯示的畫面,還是後續更具內容的畫面。

另一種觀點是,將重點放在最大內容繪製 (LCP) (甚至是首次顯示內容所需時間 (FCP)) 的時間,做為內容繪製路徑 (或其他人稱為關鍵路徑) 的一部分。在這種情況下,您可能需要納入不一定會阻斷的資源 (這是關鍵算繪路徑的典型定義),但這些資源對於算繪含有內容的塗色作業而言是必要的。

無論您如何定義「重要」內容,瞭解初始轉譯作業和重要內容的延遲原因都很重要。首次繪製是指為使用者呈現任何內容的首次可能機會。理想情況下,這應是具有意義的內容,例如背景顏色。但即使沒有內容,向使用者呈現「某物」仍有其價值,這是用來評估關鍵算繪路徑的引數,這項概念已在傳統定義中定義。同時,測量主要內容向使用者顯示的時間點也有價值。

找出含有內容的轉譯路徑

許多工具都能識別 LCP 元素,以及這些元素的算繪時間。除了LCP 元素,Lighthouse 也會協助找出LCP 階段,並顯示各階段所需的時間,協助您瞭解應將最佳化工作重點放在哪裡:

Lighthouse 的 LCP 稽核,可顯示網頁的 LCP 元素,以及 TTFB、載入延遲、載入時間和轉譯延遲等階段所花費的時間。
Lighthouse 的 LCP 稽核。

對於較複雜的網站,Lighthouse 也會在單獨的稽核中醒目顯示重大要求的鏈結

Lighthouse 的關鍵要求鏈結圖表,顯示哪些關鍵資源會巢狀在其他關鍵資源下方,以及關鍵要求鏈結的總延遲時間。
Lighthouse 關鍵要求鏈結圖表。

這項 Lighthouse 稽核作業會觀察所有以高優先順序載入的資源,因此會納入 Chrome 設為高優先順序資源的網路字型和其他內容,即使實際上並未造成轉譯阻斷也一樣。

學以致用

關鍵轉譯路徑指的是什麼?

完整轉譯網頁所需的資源最少量。
請再試一次。
執行初始網頁轉譯作業所需的資源最少數量。
答對了!

關鍵算繪路徑涉及哪些資源?

HTML 的一部分。
答對了!
<head> 元素中的轉譯封鎖 CSS。
答對了!
<head> 元素中的轉譯封鎖 JavaScript。
答對了!

為什麼轉譯阻斷是網頁轉譯的必要部分?

避免網頁在初始顯示時處於無法使用或明顯無效的狀態。
答對了!
在網頁完全轉譯完成前,避免使用者看到網頁。
請再試一次。

JavaScript 為何會封鎖 HTML 剖析器 (假設 <script> 元素未指定 deferasyncmodule 屬性)?

如果沒有上述至少一個屬性,<script> 就會阻斷剖析器和轉譯器。
答對了!
無論屬性為何,所有 JavaScript 都會阻斷剖析器。
請再試一次。
解析器到達同步 JavaScript 時,必須執行該程式碼,因為它可能會變更 DOM。
答對了!

下一篇:最佳化資源載入

本模組介紹了瀏覽器如何轉譯網頁的部分理論,特別是完成網頁初始轉譯作業所需的內容。在下一單元中,我們將說明如何透過最佳化資源載入,進而改善這個轉譯路徑。