預先載入重要素材資源,以加快載入速度

開啟網頁時,瀏覽器會向伺服器要求 HTML 文件、剖析內容,並為所有參照資源提交個別要求。身為開發人員,您一定知道網頁需要哪些資源,以及哪些資源最重要。您可以運用這項知識,預先要求重要資源,加快載入程序。這篇文章說明如何使用 <link rel="preload"> 達成這個目標。

預先載入的運作方式

預先載入最適合瀏覽器通常會延遲探索的資源。

Chrome 開發人員工具「網路」面板的螢幕截圖。
在這個範例中,樣式表會使用 @font-face 規則定義 Pacifico 字型。瀏覽器只會在下載並剖析完樣式表後,才載入字型檔案。

預先載入特定資源時,您會告知瀏覽器,您確定該資源對目前網頁很重要,因此希望瀏覽器比平常更早擷取該資源。

套用預先載入後,Chrome 開發人員工具「網路」面板的螢幕截圖。
在本範例中,系統會預先載入 Pacifico 字型,因此下載作業會與樣式表平行進行。

關鍵要求鏈結代表瀏覽器優先擷取的資源順序。Lighthouse 會將這個鏈結第三層的資產識別為延遲探索。您可以使用「預先載入關鍵要求」稽核,找出要預先載入的資源。

Lighthouse 的預先載入關鍵要求稽核。

如要預先載入資源,請在 HTML 文件的標題中加入含有 rel="preload"<link> 標記:

<link rel="preload" as="script" href="critical.js">

瀏覽器會快取預先載入的資源,以便在需要時立即使用。(不會執行指令碼或套用樣式表)。

資源提示 (例如 preconnectprefetch) 會在瀏覽器認為適當的時機執行。但 preload 對於瀏覽器而言是必要條件。現代瀏覽器已能妥善安排資源優先順序,因此請盡量避免使用 preload,只預先載入最重要的資源。

Chrome 會在 load 事件發生後約 3 秒,針對未使用的預先載入項目觸發控制台警告。

Chrome 開發人員工具控制台會顯示未使用的預先載入資源警告。

用途

預先載入 CSS 中定義的資源

瀏覽器下載並剖析 CSS 檔案後,才會發現以 @font-face 規則定義的字型,或是在 CSS 檔案中定義的背景圖片。預先載入這些資源可確保系統在下載 CSS 檔案前擷取這些資源。

預先載入 CSS 檔案

如果您採用重要 CSS 方法,請將 CSS 分成兩部分。轉譯不需捲動位置內容所需的 CSS 會內嵌在文件的 <head> 中,而重要性較低的 CSS 通常會透過 JavaScript 延遲載入。等待 JavaScript 執行完畢再載入重要性較低的 CSS,可能會導致使用者捲動時延遲算繪,因此建議使用 <link rel="preload"> 盡早啟動下載作業。

預先載入 JavaScript 檔案

由於瀏覽器不會執行預先載入的檔案,因此預先載入有助於將擷取作業與執行作業分開,進而改善互動時間等指標。如果分割 JavaScript 組合,並只預先載入重要區塊,預先載入功能就能發揮最大效益。

如何導入 rel=preload

如要導入 preload,最簡單的方法是在文件的 <head> 中加入 <link> 標記:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

提供 as 屬性可協助瀏覽器根據預先擷取資源的類型設定優先順序、設定正確的標頭,以及判斷資源是否已存在於快取中。這項屬性可接受的值包括:scriptstylefontimage其他

部分類型的資源 (例如字型) 會以匿名模式載入。您必須使用 preload 設定 crossorigin 屬性:

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

<link> 元素也接受 type 屬性,其中包含連結資源的 MIME 類型。瀏覽器會使用 type 屬性的值,確保只有在支援資源的檔案類型時,才會預先載入資源。如果瀏覽器不支援指定的資源類型,就會忽略 <link rel="preload">

您也可以透過 Link HTTP 標頭預先載入任何類型的資源:

Link: </css/style.css>; rel="preload"; as="style"

在 HTTP 標頭中指定 preload 的好處是,瀏覽器不必剖析文件即可探索,在某些情況下可稍微提升效能。

使用 webpack 預先載入 JavaScript 模組

如果您使用的模組打包工具會建立應用程式的建構檔案,請確認該工具是否支援插入預先載入標記。使用 webpack 4.6.0 以上版本時,可透過 import() 內的魔法註解支援預先載入:

import(_/* webpackPreload: true */_ "CriticalChunk")

如果使用舊版 webpack,請使用 preload-webpack-plugin 等第三方外掛程式。

預先載入對網站體驗核心指標的影響

預先載入是一項強大的效能最佳化功能,可提升載入速度。這類最佳化作業可能會導致網站的 Core Web Vitals 發生變化,因此請務必留意。

最大內容繪製 (LCP)

就字型和圖片而言,預先載入對最大內容繪製 (LCP) 有顯著影響,因為圖片和文字節點都可以是 LCP 候選項目。使用網頁字型算繪的輪播圖片和大量文字,可透過適當位置的預先載入提示大幅提升效能,因此當有機會更快向使用者提供這些重要內容時,就應使用預先載入提示。

不過,預先載入和其他最佳化作業都必須謹慎處理!特別是避免預先載入過多資源。如果優先處理的資源過多,實際上就等於沒有。如果網路速度較慢,頻寬爭用情況會更加明顯,過多的預先載入提示對這類使用者造成的影響也特別嚴重。

請改為著重於幾個高價值資源,並確定這些資源能從預先載入功能中獲益。預先載入字型時,請務必以 WOFF 2.0 格式提供字型,盡可能縮短資源載入時間。由於 WOFF 2.0 支援的瀏覽器非常廣泛,如果 LCP 候選項目是文字節點,使用 WOFF 1.0 或 TrueType (TTF) 等舊版格式會延遲 LCP。

就 LCP 和 JavaScript 而言,您需要確保從伺服器傳送完整的標記,瀏覽器的預先載入掃描器才能正常運作。如果您提供的體驗完全依賴 JavaScript 轉譯標記,且無法傳送伺服器轉譯的 HTML,建議您在瀏覽器預先載入掃描器無法運作時介入,並預先載入資源,否則這些資源只會在 JavaScript 完成載入和執行時才會被發現。

累計版面配置位移 (CLS)

累計版面配置位移 (CLS) 是與網頁字型相關的重要指標,而 CLS 與使用 font-display CSS 屬性管理字型載入方式的網頁字型有顯著的相互作用。如要盡量減少網頁字型造成的版面配置位移,請考慮採用下列策略:

  1. 使用 font-display 的預設 block 值時,預先載入字型。這需要謹慎拿捏。如果沒有備用字型,導致字型無法顯示,可視為使用者體驗問題。一方面,使用 font-display: block; 載入字型可避免網頁字型導致版面配置位移。另一方面,如果網頁字型對使用者體驗至關重要,您還是希望盡快載入這些字型。將預先載入與 font-display: block; 結合使用,或許是可接受的折衷方案。
  2. 使用 font-displayfallback 值時,預先載入字型。fallbackswapblock 之間的折衷方案,因為它的封鎖期極短。
  3. 針對沒有預先載入的 font-display 使用 optional 值。如果網頁字型對使用者體驗來說並非至關重要,但仍用於算繪大量網頁文字,請考慮使用 optional 值。在不利的條件下,optional 會以備用字型顯示網頁文字,同時在背景載入字型,以供下次瀏覽使用。在這些情況下,系統字型會立即算繪,後續網頁載入時也會立即載入字型,不會發生版面配置位移,因此 CLS 會有所改善。

就網頁字型而言,CLS 是難以最佳化的指標。如常在實驗室中進行實驗,但請相信實際資料,判斷字型載入策略是否改善 CLS,或導致 CLS 變差。

Interaction to Next Paint (INP)

與下一個顯示的內容互動指標可評估網頁對使用者輸入內容的回應速度。由於網路上大部分的互動都是由 JavaScript 驅動,因此預先載入支援重要互動的 JavaScript,有助於降低網頁的 INP。不過請注意,如果在啟動期間預先載入過多 JavaScript,可能會導致過多資源爭用頻寬,進而造成非預期的負面影響。

此外,您也需要謹慎處理程式碼分割。程式碼分割是減少啟動期間載入的 JavaScript 數量,但如果互動依賴在互動開始時載入的 JavaScript,互動可能會延遲。為此,您需要檢查使用者的意圖,並在互動發生前,為必要的 JavaScript 區塊插入預先載入。舉例來說,當表單中的任何欄位成為焦點時,您可能會預先載入驗證表單內容所需的 JavaScript。

結論

如要提升網頁速度,請預先載入瀏覽器稍後才發現的重要資源。預先載入所有內容會適得其反,因此請preload謹慎使用,並評估實際影響