rel=preload
<link> 元素的 <link> 屬性的 rel 屬性的 preload 值允許您在 HTML 的 <head> 中宣告提取請求,指定頁面很快將需要的資源,您希望在頁面生命週期的早期開始載入這些資源,在瀏覽器的主要渲染機制啟動之前。這確保它們可以更早地可用,並且不太可能阻塞頁面的渲染,從而提高效能。即使名稱包含術語“載入”,它也不會載入和執行指令碼,而只是將其安排以更高的優先順序下載和快取。
基礎知識
您最常使用 <link> 載入 CSS 檔案以使用樣式設定您的頁面
<link rel="stylesheet" href="styles/main.css" />
但是,在這裡,我們將使用 rel 值 preload,它將 <link> 變成我們想要的任何資源的預載入器。您還需要指定
一個簡單的示例可能如下所示(參見我們的JS 和 CSS 示例原始碼,以及線上示例)。
<head>
<meta charset="utf-8" />
<title>JS and CSS preload example</title>
<link rel="preload" href="style.css" as="style" />
<link rel="preload" href="main.js" as="script" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>bouncing balls</h1>
<canvas></canvas>
<script src="main.js" defer></script>
</body>
在這裡,我們預載入 CSS 和 JavaScript 檔案,以便在稍後頁面渲染需要時立即可用。此示例很簡單,因為瀏覽器可能會在與預載入相同的 HTML 塊中發現<link rel="stylesheet"> 和<script> 元素,但是當發現的資源越晚且資源越大時,好處就會更加明顯。例如
- 從 CSS 內部指向的資源,例如字型或影像。
- JavaScript 可以請求的資源,例如匯入的指令碼。
preload 還有其他優點。使用as 指定要預載入的內容型別允許瀏覽器
可以預載入哪些型別的內容?
可以預載入許多內容型別。可能的as 屬性值為
fetch:透過 fetch 或 XHR 請求訪問的資源,例如 ArrayBuffer、WebAssembly 二進位制檔案或 JSON 檔案。font:字型檔案。image:影像檔案。script:JavaScript 檔案。style:CSS 樣式表。track:WebVTT 檔案。
注意:font 和fetch 預載入需要設定crossorigin 屬性;請參閱下面的支援 CORS 的獲取。
注意:有關這些值以及它們期望被哪些 Web 功能使用的更多詳細資訊,請參閱 HTML 規範 - 請參閱連結型別“preload”。另請注意,as 屬性可以取值的完整列表受 Fetch 規範控制 - 請參閱請求目標。
包含 MIME 型別
<link> 元素可以接受type 屬性,其中包含元素指向的資源的 MIME 型別。這在預載入資源時特別有用 - 瀏覽器將使用type 屬性值來確定它是否支援該資源,如果支援,則只下載它,否則忽略它。
<head>
<meta charset="utf-8" />
<title>Image preload example</title>
<link rel="preload" href="flower.avif" as="image" type="image/avif" />
</head>
<body>
<picture>
<source src="flower.avif" type="image/avif" />
<source src="flower.webp" type="image/webp" />
<img src="flower.jpg" />
</picture>
</body>
上面示例中的程式碼導致僅在支援的瀏覽器中預載入image/avif 影像 - 對於瀏覽器中具有image/avif 支援的使用者,導致實際使用image/avif 影像(因為它是在指定的第一個<source>)。這使得希望為在瀏覽器中具有image/avif 支援的使用者下載更小的影像。
請注意,對於瀏覽器同時支援image/avif 和image/webp 的使用者,如果在該程式碼中還指定了<link rel="preload" href="flower.webp" as="image" type="image/webp"> 元素,則會預載入image/avif 和image/webp 影像 - 即使實際上只會使用其中一個。
因此,不建議為同一資源的多種型別指定預載入。相反,最佳實踐是僅為大多數使用者可能實際使用的型別指定預載入。這就是上面示例中的程式碼未指定為image/webp 影像預載入的原因。
但是,缺少預載入並不會阻止image/webp 影像被需要它的人使用:對於瀏覽器不支援image/avif 但支援image/webp 的使用者,上面示例中的程式碼仍然會導致使用image/webp 影像 - 但它是在不也為大多數其他使用者不必要地預載入的情況下實現的。
支援 CORS 的提取
預載入使用CORS 啟用的資源(例如fetch()、XMLHttpRequest 或字型)時,需要特別注意設定crossorigin 屬性在你的<link> 元素上。即使獲取不是跨域的,也需要將屬性設定為與資源的 CORS 和憑據模式匹配。
如上所述,這適用的一種有趣情況是字型檔案。由於各種原因,必須使用匿名模式 CORS 獲取這些檔案(請參閱字型獲取要求)。
讓我們以這種情況為例。您可以在 GitHub 上檢視完整的示例原始碼(也可以線上檢視)。
<head>
<meta charset="utf-8" />
<title>Web font example</title>
<link
rel="preload"
href="fonts/cicle_fina-webfont.woff2"
as="font"
type="font/woff2"
crossorigin />
<link
rel="preload"
href="fonts/zantroke-webfont.woff2"
as="font"
type="font/woff2"
crossorigin />
<link href="style.css" rel="stylesheet" />
</head>
<body>
…
</body>
我們不僅在type 屬性中提供 MIME 型別提示,而且還提供crossorigin 屬性以確保預載入的 CORS 模式與最終的字型資源請求匹配。
包含媒體
<link> 元素的一個很好的功能是它們能夠接受media 屬性。這些可以接受媒體型別 或完整的媒體查詢,允許你進行響應式預載入!
讓我們來看一個例子(在 GitHub 上檢視 - 原始碼,線上示例)。
<head>
<meta charset="utf-8" />
<title>Responsive preload example</title>
<link
rel="preload"
href="bg-image-narrow.png"
as="image"
media="(max-width: 600px)" />
<link
rel="preload"
href="bg-image-wide.png"
as="image"
media="(min-width: 601px)" />
<link rel="stylesheet" href="main.css" />
</head>
<body>
<header>
<h1>My site</h1>
</header>
<script>
const mediaQueryList = window.matchMedia("(max-width: 600px)");
const header = document.querySelector("header");
if (mediaQueryList.matches) {
header.style.backgroundImage = "url(bg-image-narrow.png)";
} else {
header.style.backgroundImage = "url(bg-image-wide.png)";
}
</script>
</body>
我們在<link> 元素上包含media 屬性,以便如果使用者具有窄視口,則預載入窄影像,如果他們具有寬視口,則載入寬影像。我們使用Window.matchMedia / MediaQueryList 來執行此操作(有關更多資訊,請參閱測試媒體查詢)。
這使得字型更有可能在頁面渲染時可用,從而減少了 FOUT(未設定樣式文字的閃爍)。
這不必侷限於影像,甚至不必是相同型別的檔案 - 想得大一點!例如,如果使用者在頻寬和 CPU 可能會更有限的窄螢幕上,你可以預載入並顯示一個簡單的 SVG 圖表,或者預載入一個複雜的 JavaScript 塊,然後使用它來渲染互動式 3D 模型,如果使用者的資源更豐富。
指令碼和預載入
注意:如果你正在使用JavaScript 模組,請改用<link rel="modulepreload">。
這些預載入的另一個優點是你可以使用指令碼執行它們。例如,這裡我們建立一個HTMLLinkElement 例項,然後將其附加到 DOM
const preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);
這意味著瀏覽器將預載入myscript.js 檔案,但尚未實際使用它。要使用它,你可以這樣做
const preloadedScript = document.createElement("script");
preloadedScript.src = "myscript.js";
document.body.appendChild(preloadedScript);
當你想預載入指令碼,但推遲執行到真正需要它的時候,這很有用。
規範
| 規範 |
|---|
| HTML 標準 # link-type-preload |
瀏覽器相容性
BCD 表格僅在啟用 JavaScript 的瀏覽器中載入。
另請參閱
- 推測性載入,用於比較
<link rel="preload">和其他類似的效能改進功能。 - 預載入:它有什麼用? 由 Yoav Weiss 撰寫