rel=preload

<link> 元素的 <link> 屬性的 rel 屬性的 preload 值允許您在 HTML 的 <head> 中宣告提取請求,指定頁面很快將需要的資源,您希望在頁面生命週期的早期開始載入這些資源,在瀏覽器的主要渲染機制啟動之前。這確保它們可以更早地可用,並且不太可能阻塞頁面的渲染,從而提高效能。即使名稱包含術語“載入”,它也不會載入和執行指令碼,而只是將其安排以更高的優先順序下載和快取。

基礎知識

您最常使用 <link> 載入 CSS 檔案以使用樣式設定您的頁面

html
<link rel="stylesheet" href="styles/main.css" />

但是,在這裡,我們將使用 relpreload,它將 <link> 變成我們想要的任何資源的預載入器。您還需要指定

  • 資源在`href` 屬性中的路徑。
  • 資源型別在`as` 屬性中。

一個簡單的示例可能如下所示(參見我們的JS 和 CSS 示例原始碼,以及線上示例)。

html
<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 指定要預載入的內容型別允許瀏覽器

  • 將其儲存在快取中以供將來請求使用,並在適當情況下重複使用資源。
  • 對資源應用正確的內容安全策略
  • 為其設定正確的Accept 請求頭。

可以預載入哪些型別的內容?

可以預載入許多內容型別。可能的as 屬性值為

  • fetch:透過 fetch 或 XHR 請求訪問的資源,例如 ArrayBuffer、WebAssembly 二進位制檔案或 JSON 檔案。
  • font:字型檔案。
  • image:影像檔案。
  • script:JavaScript 檔案。
  • style:CSS 樣式表。
  • track:WebVTT 檔案。

注意:fontfetch 預載入需要設定crossorigin 屬性;請參閱下面的支援 CORS 的獲取

注意:有關這些值以及它們期望被哪些 Web 功能使用的更多詳細資訊,請參閱 HTML 規範 - 請參閱連結型別“preload”。另請注意,as 屬性可以取值的完整列表受 Fetch 規範控制 - 請參閱請求目標

包含 MIME 型別

<link> 元素可以接受type 屬性,其中包含元素指向的資源的 MIME 型別。這在預載入資源時特別有用 - 瀏覽器將使用type 屬性值來確定它是否支援該資源,如果支援,則只下載它,否則忽略它。

html
<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/avifimage/webp 的使用者,如果在該程式碼中還指定了<link rel="preload" href="flower.webp" as="image" type="image/webp"> 元素,則會預載入image/avifimage/webp 影像 - 即使實際上只會使用其中一個。

因此,不建議為同一資源的多種型別指定預載入。相反,最佳實踐是僅為大多數使用者可能實際使用的型別指定預載入。這就是上面示例中的程式碼未指定為image/webp 影像預載入的原因。

但是,缺少預載入並不會阻止image/webp 影像被需要它的人使用:對於瀏覽器不支援image/avif 但支援image/webp 的使用者,上面示例中的程式碼仍然會導致使用image/webp 影像 - 但它是在不也為大多數其他使用者不必要地預載入的情況下實現的。

支援 CORS 的提取

預載入使用CORS 啟用的資源(例如fetch()XMLHttpRequest字型)時,需要特別注意設定crossorigin 屬性在你的<link> 元素上。即使獲取不是跨域的,也需要將屬性設定為與資源的 CORS 和憑據模式匹配。

如上所述,這適用的一種有趣情況是字型檔案。由於各種原因,必須使用匿名模式 CORS 獲取這些檔案(請參閱字型獲取要求)。

讓我們以這種情況為例。您可以在 GitHub 上檢視完整的示例原始碼也可以線上檢視)。

html
<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 上檢視 - 原始碼線上示例)。

html
<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

js
const preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);

這意味著瀏覽器將預載入myscript.js 檔案,但尚未實際使用它。要使用它,你可以這樣做

js
const preloadedScript = document.createElement("script");
preloadedScript.src = "myscript.js";
document.body.appendChild(preloadedScript);

當你想預載入指令碼,但推遲執行到真正需要它的時候,這很有用。

規範

規範
HTML 標準
# link-type-preload

瀏覽器相容性

BCD 表格僅在啟用 JavaScript 的瀏覽器中載入。

另請參閱