延後不重要的 CSS

Demián Renzulli
Demián Renzulli

CSS 檔案是妨礙顯示的資源:瀏覽器必須先載入及處理這些檔案,才能算繪網頁。如果網頁包含不必要的大型樣式表,就會需要較長的時間才能顯示。

瞭解如何延遲載入非重要 CSS,藉此最佳化重要算繪路徑,並改善首次內容繪製 (FCP)

CSS 載入效率不佳

以下範例包含一個手風琴,內有三段隱藏文字,每段文字都採用不同的類別設定樣式:

這個頁面要求含有八個類別的 CSS 檔案,但並非所有類別都必須用於算繪「可見」內容。

本指南的目標是最佳化這個頁面,只同步載入重要樣式,其餘樣式 (包括段落樣式) 則以非阻斷方式載入。

評估

在開發人員工具中執行 Lighthouse,查看重要指標。

  1. 在 Chrome 中開啟試用版
  2. 開啟 Chrome 開發人員工具
  3. 選取「效能」面板
  4. 在面板中重新載入頁面。

報表會顯示「首次顯示內容所需時間」指標,值為「1 秒」,以及「排除會阻礙算繪的資源」改善建議,並指出 style.css 檔案:

未經過最佳化的網頁的 Lighthouse 報表,顯示「1 秒」的 FCP,以及「商機」下方的「排除會阻斷轉譯的資源」
Lighthouse 報表建議簡化樣式表,加快網頁載入速度。

在產生的追蹤記錄中,FCP 標記會放在 CSS 載入完成後:

未經過最佳化的網頁的開發人員工具效能追蹤記錄,顯示 FCP 在 CSS 載入後開始。
在未經過最佳化的示範網頁上,CSS 載入完成前,無法發生 FCP。

也就是說,瀏覽器必須等待所有 CSS 載入並處理完畢,才能在畫面上繪製單一像素。

最佳化

如要最佳化這個頁面,請使用涵蓋範圍工具,判斷哪些類別屬於重要類別。

  1. 按下 Control+Shift+PCommand+Shift+P (Mac),開啟開發人員工具的「指令選單」
  2. 輸入「涵蓋範圍」,然後選取「顯示涵蓋範圍」
  3. 按一下「重新載入」,重新載入網頁並開始擷取涵蓋範圍。
CSS 檔案的涵蓋範圍,顯示 55.9% 的未使用位元組。
涵蓋範圍報表會顯示在初始網頁載入時,實際使用的 CSS 數量。

按兩下報表即可查看詳細資料:

  • 標示為綠色的類別至關重要。瀏覽器需要這些資訊才能顯示可見內容,包括標題、副標題和手風琴按鈕。
  • 以紅色標示的類別並不重要,只會影響非立即顯示的內容,例如隱藏的段落。

有了這項資訊,您就能最佳化 CSS,讓瀏覽器在網頁載入後立即開始處理重要樣式,並延後處理非重要 CSS:

  1. 從涵蓋範圍報告中擷取以綠色標示的類別定義,並將這些類別放在網頁開頭的 <style> 區塊中:

    <style type="text/css">
    .accordion-btn {background-color: #ADD8E6;color: #444;cursor: pointer;padding: 18px;width: 100%;border: none;text-align: left;outline: none;font-size: 15px;transition: 0.4s;}.container {padding: 0 18px;display: none;background-color: white;overflow: hidden;}h1 {word-spacing: 5px;color: blue;font-weight: bold;text-align: center;}
    </style>
    
  2. 套用下列模式,以非同步方式載入其餘類別:

    <link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
    <noscript><link rel="stylesheet" href="styles.css"></noscript>
    

這不是載入 CSS 的標準方式。運作方式如下:

  • link rel="preload" as="style" 會以非同步方式要求樣式表。如要進一步瞭解 preload,請參閱預先載入重要素材資源指南
  • link 中的 onload 屬性可讓瀏覽器在樣式表載入完成時處理 CSS。
  • onload 處理常式使用完畢後「將其設為空值」,有助於某些瀏覽器避免在切換 rel 屬性時重新呼叫處理常式。
  • noscript 元素內的樣式表參照,可為不執行 JavaScript 的瀏覽器提供備援。

實際運作中

在正式環境中,建議使用 CSS 延遲函式 (例如 loadCSS),封裝這項行為,並在各個瀏覽器中正常運作。這些函式支援內容安全政策,可能不允許內嵌 onload JavaScript。

您也可以將 CSS 連結放在網頁底部,這樣內容在瀏覽器載入樣式表時,可能就不必等待即可顯示。 不過,瀏覽器仍會優先處理樣式表,因此仍可能封鎖瀏覽器中的重要內容。

即使大部分樣式都是非同步載入,產生的網頁看起來也與先前版本完全相同。

監控

使用開發人員工具,在最佳化網頁上執行另一項「效能」追蹤。

FCP 標記會顯示在網頁要求 CSS 之前,這表示瀏覽器不需要等待 CSS 載入,即可算繪網頁:

最佳化網頁的開發人員工具效能追蹤記錄,顯示 FCP 在 CSS 載入前開始。
在最佳化網頁上,FCP 可以在樣式表載入前啟動。

最後一個步驟是在最佳化網頁上執行 Lighthouse。

在報表中,您會看到 FCP 網頁減少了 0.2 秒 (改善了 20%!):

Lighthouse 報告,顯示 FCP 值為「0.8 秒」。

「排除會妨礙顯示的資源」建議不再顯示在「改善機會」下方,而是顯示在「通過稽核」部分:

Lighthouse 報表圖片,顯示「已通過的稽核」部分中的「排除會阻斷轉譯的資源」。
網頁現在通過了妨礙顯示的資源稽核。

後續步驟和參考資料

如要瞭解更複雜的製作環境,請參閱擷取重要 CSS 指南,其中涵蓋一些最熱門的擷取重要 CSS 工具,並提供程式碼研究室,讓您瞭解這些工具的實際運作方式。