當您開啟網頁時,瀏覽器會向伺服器要求 HTML 文件、剖析其內容,然後針對任何參照的資源提交個別的要求。開發人員一定已經掌握了網頁所需的所有資源,並知道哪些資源最重要。您可以運用這些資訊,預先要求重要資源,並加快載入速度。本文說明如何使用 <link rel="preload">
達成這個目標。
預先載入機制的運作方式
預先載入最適合瀏覽器遲到後發現的資源。
![Chrome 開發人員工具「Network」面板的螢幕截圖。](https://web.developers.google.cn/static/articles/preload-critical-assets/image/screenshot-devtools-1.png?authuser=19&hl=zh-tw)
@font-face
規則,在樣式表中定義 Pacifico 字型。瀏覽器只有在字型檔案下載完畢並剖析樣式表後,才會載入字型檔案。預先載入某項資源,即代表您確定瀏覽器收集這個資源的時間,比瀏覽器發現的速度更快,因為您確定目前的網頁很重要。
![套用預先載入功能後,Chrome 開發人員工具「Network」面板的螢幕截圖。](https://web.developers.google.cn/static/articles/preload-critical-assets/image/screenshot-chrome-devtoo-debf067f48e5c.png?authuser=19&hl=zh-tw)
關鍵要求鏈代表瀏覽器優先處理和擷取的資源順序。Lighthouse 會將此鏈中第三層的資產識別為晚期發現的資產。您可以透過預先載入金鑰要求稽核功能,找出要預先載入的資源。
只要在 HTML 文件的標題中加入包含 rel="preload"
的 <link>
標記,即可預先載入資源:
<link rel="preload" as="script" href="critical.js">
瀏覽器會快取預先載入的資源,以便在需要時立即使用。(不會執行指令碼或套用樣式表)。
資源提示 (例如 preconnect
和 prefetch
) 會在瀏覽器確定的適當時機執行。另一方面,瀏覽器必須使用 preload
。新式瀏覽器非常適合用來排定資源的優先順序,因此請謹慎使用 preload
,並僅預先載入最重要的資源。
未使用的預先載入功能會在 Chrome 發生 load
事件約 3 秒後觸發控制台警告。
用途
預先載入 CSS 中定義的資源
瀏覽器下載並剖析 CSS 檔案後,才會找到使用 @font-face
規則定義的字型或 CSS 檔案中定義的背景圖片。預先載入這些資源,可確保系統會在 CSS 檔案下載前擷取這些資源。
預先載入 CSS 檔案
如果您採用重要的 CSS 方法,請將 CSS 分為兩個部分。用來轉譯前幾行內容所需的重要 CSS 已內嵌於文件的 <head>
中,而不重要的 CSS 通常會透過 JavaScript 延遲載入。在載入不重要的 CSS 之前等待 JavaScript 執行完畢,可能會導致使用者在捲動時延遲顯示,因此建議您使用 <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 的必要區塊插入預先載入項目。例如在聚焦表單中的任何欄位時,預先載入的 JavaScript 是用來驗證表單內容。
結論
如要加快網頁載入速度,請預先載入瀏覽器遲到的重要資源。預先載入所有項目可能會導致收益反感,因此請謹慎使用 preload
,並評估實際情形。