您開啟網頁時,瀏覽器會向伺服器要求 HTML 文件、剖析其中內容,並分別提出任何參照資源的要求。身為開發人員,您已經知道網頁需要的所有資源,以及哪些資源最重要。您可以運用這些資訊,事先要求重要資源並加快載入速度。本文將說明如何運用 <link rel="preload">
達成此目標。
預先載入的運作方式
預先載入功能最適合瀏覽器延遲發現的資源。
預先載入特定資源後,就表示您確定這是目前網頁的重要,因此您希望瀏覽器更快擷取該資源。
關鍵要求鏈代表瀏覽器優先順序和擷取的資源順序。Lighthouse 會做出延遲發現,並識別在這個鏈結第三層的資產。您可以使用預先載入金鑰要求稽核來找出要預先載入的資源。
如要預先載入資源,請在 HTML 文件的標題中加入含有 rel="preload"
的 <link>
標記:
<link rel="preload" as="script" href="critical.js">
瀏覽器會快取預先載入的資源,以便在需要時立即使用。(系統不會執行指令碼或套用樣式表)。
瀏覽器會視實際情況執行資源提示 (例如 preconnect
和 prefetch
)。另一方面,preload
是瀏覽器的必要項目,新式瀏覽器已擅長安排資源的優先順序,因此請謹慎使用 preload
,並且僅預先載入最重要的資源。
未使用的預先載入功能會在 load
事件大約 3 秒後觸發 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
屬性可協助瀏覽器根據類型設定預先擷取資源的優先順序、設定正確的標頭,並判斷快取中是否已有該資源。這個屬性接受的值包括:script
、style
、font
、image
和其他。
有些類型的資源 (例如字型) 是以匿名模式載入。如果是這種情況,則必須使用 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 屬性管理字型載入方式的網頁字型之間有顯著的交互作用。為了盡量減少與網頁字型相關的版面配置位移,請考慮以下策略:
- 預先載入字型,同時使用
font-display
的預設值block
。這可是相當精細的餘額。如果在沒有備用選項的情況下封鎖字型顯示,可能會帶來使用者體驗問題。一方面使用font-display: block;
載入字型,可避免與網路字型相關的版面配置位移。另一方面,如果網頁字型對使用者體驗具有重要性,則建議您盡快載入。結合預先載入與font-display: block;
可能是可接受的入侵手段。 - 預先載入字型,並對
font-display
使用fallback
值。fallback
是swap
和block
之間的入侵,因為其封鎖期間極短。 - 在不預先載入的情況下,針對
font-display
使用optional
值。如果網頁字型對於使用者體驗來說並不重要,但仍用於顯示大量網頁文字,建議使用optional
值。相反地,optional
會在背景載入字型時,以備用字型顯示網頁文字,以供下一次瀏覽時使用。這些條件所產生的淨結果可改善 CLS,因為系統字型會立即顯示,後續載入的網頁則會在沒有版面配置位移的情況下立即載入字型。
對於網頁字型而言,CLS 是一項難以最佳化的指標。一如往常,您可以在研究室中進行實驗,但可信任您的現場資料,藉此判斷字型載入策略是否改善 CLS 或降低情況。
與下一個顯示的內容 (INP) 互動
「與下一個顯示的內容互動」指標可用於衡量使用者輸入內容的回應速度。由於網路上互動的比例是由 JavaScript 驅動,因此預先載入支援重要互動的 JavaScript,可能有助減少網頁的 INP。不過請注意,如果在啟動期間預先載入過多 JavaScript,如果太多資源佔用了頻寬,就可能會產生非預期的負面結果。
另外,也請務必留意程式碼分割的處理方法。程式碼分割是非常出色的最佳化效果,可減少啟動期間載入的 JavaScript 數量,但若仰賴在互動開始時立即載入的 JavaScript,互動可能會延遲。為了達成這個目標,您需要檢查使用者的意圖,並在互動發生前插入 JavaScript 必要區塊的預先載入內容。舉例來說,當焦點放在表單中的任何欄位時,可能會預先載入驗證表單內容所需的 JavaScript。
結論
如要加快網頁載入速度,請預先載入瀏覽器延遲發現的重要資源。預先載入所有內容都有缺點,因此請謹慎使用 preload
並評估實際影響。