延後不重要的 CSS

Demián Renzulli
Demián Renzulli

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

本指南將說明如何延後非必要的 CSS,以便最佳化關鍵轉譯路徑,並改善第一個有內容的圖片顯示時間 (FCP)

以下範例包含一個摺疊式面板,其中有三個隱藏的文字段落,每個段落都使用不同的類別設定樣式:

這個頁面會要求含有八個類別的 CSS 檔案,但並非所有類別都需要轉譯「可見」內容。

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

測量

頁面上執行 Lighthouse,然後前往「效能」部分。

這份報表顯示「首次顯示內容所需時間」指標的值為「1 秒」,並指出「消除造成轉譯阻斷的資源」機會,指向 style.css 檔案:

未經最佳化的網頁 Lighthouse 報表,顯示「Opportunities」下方的「1 秒」FCP 和「Eliminate blocking resources」
Lighthouse 報表建議您簡化樣式表單,加快網頁載入速度。

如要查看這段 CSS 如何阻斷轉譯,請按照下列步驟操作:

  1. 在 Chrome 中開啟網頁
  2. 按下 Control+Shift+J (在 Mac 上為 Command+Option+J) 開啟開發人員工具。
  3. 按一下「成效」分頁標籤。
  4. 在「Performance」面板中,按一下「Reload」

在產生的追蹤記錄中,您會看到 FCP 標記會在 CSS 載入完成後立即放置:

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

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

最佳化

如要改善這個頁面,您必須知道哪些類別屬於重要類別。如要判斷這項資訊,請使用測試涵蓋率工具

  1. 在開發人員工具中,按下 Control+Shift+PCommand+Shift+P (Mac) 開啟「指令選單」
  2. 輸入「涵蓋範圍」,然後選取「顯示涵蓋範圍」
  3. 按一下「Reload」,重新載入網頁並開始擷取涵蓋範圍。
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 的瀏覽器提供備用方案。

即使大部分樣式是以非同步方式載入,產生的網頁仍會與先前版本完全相同。以下是 HTML 檔案中內嵌樣式和 CSS 檔案的非同步要求的樣子:

監控

使用開發人員工具,在已最佳化的網頁上執行另一個效能追蹤記錄。

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

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

最後一個步驟是在經過最佳化處理的網頁上執行 Lighthouse。

在報表中,您會看到 FCP 網頁的時間已縮短 0.2 秒 (改善幅度達 20%):

Lighthouse 報表,顯示 FCP 值為「0.8 秒」。
新的 FCP 縮短時間。

「排除會妨礙顯示的資源」建議不再顯示在「Opportunities」下方,而是顯示在「Passed Audits」部分:

Lighthouse 報表的圖片,顯示「已移除封鎖資源」和「已通過的稽核項目」部分。
網頁現在已通過妨礙資源稽核。

後續步驟和參考資料

在本指南中,您瞭解如何手動擷取網頁中未使用的程式碼,以便延後非必要的 CSS。針對較複雜的實際工作環境,提取重要 CSS 指南介紹了一些最常用的提取重要 CSS 工具,並提供程式碼研究室,讓您瞭解這些工具在實際工作環境中的運作方式。