この翻訳は不完全です。英語から この記事を翻訳 してください。

<link> 要素の rel 属性で preload を指定すると、 HTML の <head> 要素内で読み込みリクエストを宣言し、ページのライフサイクルの早期の、ブラウザーの主なレンダリング機構が起動する前に読み込みを始めたい、すぐに必要なリソースを指定することができます。これにより、そのリソースがより早く利用でき、ページのレンダリングがブロックされにくくなり、性能が向上します。

この記事では <link rel="preload"> がどのように動作するのかについての基本的なガイドを提供します。

基本概念

多くの場合は以下のように、 <link> を使用して CSS ファイルを読み込み、ページにスタイルを適用します。

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

しかしここで、 rel の値に preload を使用すると、 <link> 要素は利用したいあらゆるリソースの先読み指示になります。以下のものも指定する必要があります。

  • リソースへのパスを href 属性へ。
  • リソースの種類を as 属性へ。

簡単な例は以下のようになります (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 ファイルを先読みするので、その後のページのレンダリングで必要な時には、すぐに利用できるようになります。ブラウザーはおそらく、 <link rel="stylesheet"><script> 要素を HTML 内の同じの部分で見つけるので、この例は極端ですが、後に現れるリソースであるほど、また大きいリソースであるほど効果が見られる可能性があります。例えば以下の場合です。

  • フォントや画像など、 CSS の中から指しているリソース
  • JSON やインポートされたスクリプト、ウェブワーカーなどの JavaScript がリクエストする可能性があるリソース
  • より大きな画像や動画ファイル。

preload には他の利点もあります。 as によって先読みされるコンテンツの種類をブラウザーに指示することで、以下のようなことが実現できます。

  • リソースの読み込みの優先付けがより正確にできます。
  • 可能であれば、将来のリクエストのためにキャッシュに格納してリソースを再利用します。
  • リソースに対して正しくコンテンツセキュリティポリシを適用できます。
  • 正しい Accept リクエストヘッダーを設定できます。

先読みできるコンテンツの種類

さまざまな種類のコンテンツが先読みできます。 as 属性で使用できる値は以下の通りです。

  • audio: 通常は <audio> で使用される音声ファイル。
  • document: <frame><iframe> に埋め込まれる HTML 文書。
  • embed: <embed> 要素の中に埋め込まれるリソース。
  • fetch: ArrayBuffer や JSON ファイルのような、フェッチまたは XHR 要求でアクセスされるリソース。
  • font: フォントファイル。
  • image: 画像ファイル。
  • object: <object> 要素の中に埋め込まれるリソース。
  • script: JavaScript ファイル。
  • style: CSS スタイルシート。
  • track: WebVTT ファイル。
  • worker: JavaScript ウェブワーカーまたは共有ワーカー。
  • video: 通常は <video> で使用される動画ファイル。

メモ: 使用されると予想されるこれらの値やウェブ機能について、もっと詳細は Preload の仕様書にあります。 — link element extensions を参照してください。また、フェッチの仕様書で管理されている as 属性の値の完全な一覧は、 request destinations を参照してください。

MIME タイプを含める

<link> 要素は type 要素を受け付け、要素が指す先のリソースの MIME タイプを指定することができます。これは特にリソースの先読み時に便利です。 — ブラウザーは type 属性の値を使用して対応しているリソースであるかどうかを確認し、その場合だけダウンロードを開始し、そうでない場合は開始しないようにすることができます。

この例を動画のデモで見ることができます (ソースコード全体デモ版もご覧ください。)。

<head>
  <meta charset="utf-8">
  <title>Video preload example</title>

  <link rel="preload" href="sintel-short.mp4" as="video" type="video/mp4">
</head>
<body>
  <video controls>
    <source src="sintel-short.mp4" type="video/mp4">
    <source src="sintel-short.webm" type="video/webm">
    <p>Your browser doesn't support HTML5 video. Here is a <a href="sintel-short.mp4">link to the video</a> instead.</p>
  </video>
</body>

So in this case, browsers that support MP4s will preload and use the MP4, making the video player hopefully smoother/more responsive for users. Browsers that don't support MP4 can still load the WebM version, but don't get the advantages of preloading. This shows how preloading content can be combined with the philosophy of progressive enhancement.

オリジンをまたいだフェッチ

If you've got your sites' CORS settings worked out properly, you can successfully preload cross-origin resources as long as you set a crossorigin attribute on your <link> element.

One interesting case where this applies, even if the fetch is not cross-origin, is font files. Because of various reasons, these have to be fetched using anonymous mode CORS (see Font fetching requirements).

Let's use this case as an example. You can see the full example source code on GitHub (also see it live):

<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" type="text/css">
</head>
<body>
  …
</body>

Not only are we providing the MIME type hints in the type attributes, but we are also providing the crossorigin attribute to handle the CORS issue.

media を含める

One nice feature of <link> elements is their ability to accept media attributes. These can accept media types or full-blown media queries, allowing you to do responsive preloading!

Let's look at an example (see it on GitHub — source code, live example):

<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>
    var mediaQueryList = window.matchMedia("(max-width: 600px)");
    var 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>

We include media attributes on our <link> elements so that a narrow image is preloaded if the user has a narrow viewport, and a wider image is loaded if they have a wide viewport. We use Window.matchMedia / MediaQueryList to do this (see Testing media queries for more).

This makes it much more likely that the font will be available for the page render, cutting down on FOUT (flash of unstyled text).

This doesn't have to be limited to images, or even files of the same type — think big! You could perhaps preload and display a simple SVG diagram if the user is on a narrow screen where bandwidth and CPU is potentially more limited, or preload a complex chunk of JavaScript then use it to render an interactive 3D model if the user's resources are more plentiful.

スクリプトと先読み

Another nice thing about these preloads is that you can execute them with script. For example, here we create a HTMLLinkElement instance, then attach it to the DOM:

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

This means that the browser will preload the myscript.js file, but not actually use it yet. To use it, you could do this:

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

This is useful when you want to preload a script, but then defer execution until exactly when you need it.

他のリソースの先読み機構

Other preloading features exist, but none are quite as fit for purpose as <link rel="preload">:

  • <link rel="prefetch"> has been supported in browsers for a long time, but it is intended for prefetching resources that will be used in the next navigation/page load (e.g. when you go to the next page). This is fine, but isn't useful for the current page! In addition, browsers will give prefetch resources a lower priority than preload ones — the current page is more important than the next. See Link prefetching FAQ for more details.
  • <link rel="prerender"> renders a specified webpage in the background, speeding up its load if the user navigates to it. Because of the potential to waste users bandwidth, Chrome treats prerender as a NoState prefetch instead.
  • <link rel="subresource"> was supported in Chrome a while ago, and was intended to tackle the same issue as preload, but it had a problem: there was no way to work out a priority for the items (as didn't exist back then), so they all got fetched with fairly low priority.
  • There are a number of script-based resource loaders out there, but they don't have any power over the browser's fetch prioritization queue, and are subject to much the same performance problems.

仕様書

仕様書 状態 備考
Preload
preload の定義
勧告候補 preload の詳細
HTML Living Standard
rel=preload の定義
現行の標準 preload の定義

ブラウザーの対応

Update compatibility data on GitHub
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung Internet
preload
実験的
Chrome 完全対応 50Edge ? Firefox 未対応 56 — 57
補足
未対応 56 — 57
補足
補足 Disabled due to various web compatibility issues (e.g. bug 1405761).
IE ? Opera 完全対応 37Safari ? WebView Android 完全対応 50Chrome Android 完全対応 50Firefox Android 未対応 56 — 57
補足
未対応 56 — 57
補足
補足 Disabled due to various web compatibility issues (e.g. bug 1405761).
Opera Android ? Safari iOS ? Samsung Internet Android 完全対応 5.0

凡例

完全対応  
完全対応
未対応  
未対応
実装状況不明  
実装状況不明
実験的。動作が変更される可能性があります。
実験的。動作が変更される可能性があります。
実装ノートを参照してください。
実装ノートを参照してください。

関連情報

ドキュメントのタグと貢献者

このページの貢献者: mfuji09, mdnwebdocs-bot, turenar
最終更新者: mfuji09,