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

您開啟網頁時,瀏覽器會向伺服器要求 HTML 文件、剖析其中內容,並分別提出任何參照資源的要求。身為開發人員,您已經知道網頁需要的所有資源,以及哪些資源最重要。您可以運用這些資訊,事先要求重要資源並加快載入速度。本文將說明如何運用 <link rel="preload"> 達成此目標。

預先載入的運作方式

預先載入功能最適合瀏覽器延遲發現的資源。

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

預先載入特定資源後,就表示您確定這是目前網頁的重要,因此您希望瀏覽器更快擷取該資源。

套用預先載入的 Chrome 開發人員工具「Network」面板螢幕截圖。
在這個例子中,Pacifico 字型已預先載入,因此下載作業與樣式表同時進行。

關鍵要求鏈代表瀏覽器優先順序和擷取的資源順序。Lighthouse 會做出延遲發現,並識別在這個鏈結第三層的資產。您可以使用預先載入金鑰要求稽核來找出要預先載入的資源。

Lighthouse 預先載入金鑰要求稽核。

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

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

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

瀏覽器會視實際情況執行資源提示 (例如 preconnectprefetch)。另一方面,preload 是瀏覽器的必要項目,新式瀏覽器已擅長安排資源的優先順序,因此請謹慎使用 preload,並且僅預先載入最重要的資源。

未使用的預先載入功能會在 load 事件大約 3 秒後觸發 Chrome 的控制台警告。

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

用途

預先載入 CSS 中定義的資源

Google 不會偵測到使用 @font-face 規則定義的字型或 CSS 檔案中定義的背景圖片,直到瀏覽器下載並剖析這些 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

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

預先載入是一項強大的效能最佳化功能,會對載入速度造成影響。這類最佳化作業可能會導致網站的網站體驗核心指標發生變化,因此請務必留意。

最大內容繪製 (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-display 使用 fallback 值。fallbackswapblock 之間的入侵,因為其封鎖期間極短。
  3. 在不預先載入的情況下,針對 font-display 使用 optional 值。如果網頁字型對於使用者體驗來說並不重要,但仍用於顯示大量網頁文字,建議使用 optional 值。相反地,optional 會在背景載入字型時,以備用字型顯示網頁文字,以供下一次瀏覽時使用。這些條件所產生的淨結果可改善 CLS,因為系統字型會立即顯示,後續載入的網頁則會在沒有版面配置位移的情況下立即載入字型。

對於網頁字型而言,CLS 是一項難以最佳化的指標。一如往常,您可以在研究室中進行實驗,但可信任您的現場資料,藉此判斷字型載入策略是否改善 CLS 或降低情況。

與下一個顯示的內容 (INP) 互動

「與下一個顯示的內容互動」指標可用於衡量使用者輸入內容的回應速度。由於網路上互動的比例是由 JavaScript 驅動,因此預先載入支援重要互動的 JavaScript,可能有助減少網頁的 INP。不過請注意,如果在啟動期間預先載入過多 JavaScript,如果太多資源佔用了頻寬,就可能會產生非預期的負面結果。

另外,也請務必留意程式碼分割的處理方法。程式碼分割是非常出色的最佳化效果,可減少啟動期間載入的 JavaScript 數量,但若仰賴在互動開始時立即載入的 JavaScript,互動可能會延遲。為了達成這個目標,您需要檢查使用者的意圖,並在互動發生前插入 JavaScript 必要區塊的預先載入內容。舉例來說,當焦點放在表單中的任何欄位時,可能會預先載入驗證表單內容所需的 JavaScript。

結論

如要加快網頁載入速度,請預先載入瀏覽器延遲發現的重要資源。預先載入所有內容都有缺點,因此請謹慎使用 preload評估實際影響