1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
---
title: rel="preload" によるコンテンツの先読み
slug: Web/HTML/Preloading_content
tags:
- Guide
- HTML
- JavaScript
- Link
- Media
- Performance
- Web Performance
- as
- preload
- rel
translation_of: Web/HTML/Preloading_content
---
<p class="summary">{{htmlelement("link")}} 要素の {{htmlattrxref("rel", "link")}} 属性で <code>preload</code> を指定すると、 HTML の {{htmlelement("head")}} 要素内で読み込みリクエストを宣言し、ページのライフサイクルの早期の、ブラウザーの主なレンダリング機構が起動する前に読み込みを始めたい、すぐに必要なリソースを指定することができます。これにより、そのリソースがより早く利用でき、ページのレンダリングがブロックされにくくなり、性能が向上します。</p>
<p class="summary">この記事では <code><link rel="preload"></code> がどのように動作するのかについての基本的なガイドを提供します。</p>
<h2 id="The_basics" name="The_basics">基本概念</h2>
<p>多くの場合は以下のように、 <code><link></code> を使用して CSS ファイルを読み込み、ページにスタイルを適用します。</p>
<pre class="brush: html notranslate"><link rel="stylesheet" href="styles/main.css"></pre>
<p>しかしここで、 <code>rel</code> の値に <code>preload</code> を使用すると、 <code><link></code> 要素は利用したいあらゆるリソースの先読み指示になります。以下のものも指定する必要があります。</p>
<ul>
<li>リソースへのパスを {{htmlattrxref("href", "link")}} 属性へ。</li>
<li>リソースの種類を {{htmlattrxref("as", "link")}} 属性へ。</li>
</ul>
<p>簡単な例は以下のようになります (<a href="https://github.com/mdn/html-examples/tree/master/link-rel-preload/js-and-css">JS と CSS のサンプルコード</a> および <a href="https://mdn.github.io/html-examples/link-rel-preload/js-and-css/">デモ</a>) も参照してください)。</p>
<pre class="brush: html notranslate"><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></pre>
<p>ここで CSS ファイルと JavaScript ファイルを先読みするので、その後のページのレンダリングで必要な時には、すぐに利用できるようになります。ブラウザーはおそらく、 <code><link rel="stylesheet"></code> と <code><script></code> 要素を HTML 内の同じチャンクで見つけるので、この例は極端ですが、後に現れるリソースであるほど、また大きいリソースであるほど効果が見られる可能性があります。例えば以下の場合です。</p>
<ul>
<li>フォントや画像など、 CSS の中から指しているリソース</li>
<li>JSON やインポートされたスクリプト、ウェブワーカーなどの JavaScript がリクエストする可能性があるリソース</li>
<li>より大きな画像や動画ファイル。</li>
</ul>
<p><code>preload</code> には他の利点もあります。 <code>as</code> によって先読みされるコンテンツの種類をブラウザーに指示することで、以下のようなことが実現できます。</p>
<ul>
<li>リソースの読み込みの優先付けがより正確にできます。</li>
<li>可能であれば、将来のリクエストのためにキャッシュに格納してリソースを再利用します。</li>
<li>リソースに対して正しく<a href="/ja/docs/Web/HTTP/CSP">コンテンツセキュリティポリシー</a>を適用できます。</li>
<li>正しい {{HTTPHeader("Accept")}} リクエストヘッダーを設定できます。</li>
</ul>
<h3 id="What_types_of_content_can_be_preloaded" name="What_types_of_content_can_be_preloaded">先読みできるコンテンツの種類</h3>
<p>さまざまな種類のコンテンツが先読みできます。 <code>as</code> 属性で使用できる値は以下の通りです。</p>
<ul>
<li><code>audio</code>: 通常は {{htmlelement("audio")}} で使用される音声ファイル。</li>
<li><code>document</code>: {{htmlelement("frame")}} や {{htmlelement("iframe")}} に埋め込まれる HTML 文書。</li>
<li><code>embed</code>: {{htmlelement("embed")}} 要素の中に埋め込まれるリソース。</li>
<li><code>fetch</code>: ArrayBuffer や JSON ファイルのような、フェッチまたは XHR 要求でアクセスされるリソース。</li>
<li><code>font</code>: フォントファイル。</li>
<li><code>image</code>: 画像ファイル。</li>
<li><code>object</code>: {{htmlelement("object")}} 要素の中に埋め込まれるリソース。</li>
<li><code>script</code>: JavaScript ファイル。</li>
<li><code>style</code>: CSS スタイルシート。</li>
<li><code>track</code>: WebVTT ファイル。</li>
<li><code>worker</code>: JavaScript ウェブワーカーまたは共有ワーカー。</li>
<li><code>video</code>: 通常は {{htmlelement("video")}} で使用される動画ファイル。</li>
</ul>
<div class="note">
<p><strong>メモ</strong>: 使用されると予想されるこれらの値やウェブ機能について、もっと詳細は Preload の仕様書にあります。 — <a href="https://w3c.github.io/preload/#link-element-extensions">link element extensions</a> を参照してください。また、フェッチの仕様書で管理されている <code>as</code> 属性の値の完全な一覧は、 <a href="https://fetch.spec.whatwg.org/#concept-request-destination">request destinations</a> を参照してください。</p>
</div>
<h2 id="Including_a_MIME_type" name="Including_a_MIME_type">MIME タイプを含める</h2>
<p><code><link></code> 要素は {{htmlattrxref("type", "link")}} 要素を受け付け、要素が指す先のリソースの MIME タイプを指定することができます。これは特にリソースの先読み時に便利です。 — ブラウザーは <code>type</code> 属性の値を使用して対応しているリソースであるかどうかを確認し、その場合だけダウンロードを開始し、そうでない場合は開始しないようにすることができます。</p>
<p>この例を動画のデモで見ることができます (<a href="https://github.com/mdn/html-examples/tree/master/link-rel-preload/video">ソースコード全体</a>と<a href="https://mdn.github.io/html-examples/link-rel-preload/video/">デモ版</a>もご覧ください。)。</p>
<pre class="brush: html notranslate"><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></pre>
<p>この場合、MP4 をサポートしているブラウザーは MP4 を先読みして使用し、ユーザーにとって動画プレイヤーをよりスムーズまたはレスポンシブにできるでしょう。ブラウザーが MP4 をサポートしていない場合は WebM バージョンを読み込みますが、先読みの利点は得られません。これは、どのように先読みコンテンツがプログレッシブエンハンスメントの哲学と結ばれているかを示しています。</p>
<h2 id="Cross-origin_fetches" name="Cross-origin_fetches">オリジンをまたいだフェッチ</h2>
<p>CORSを有効にしてフェッチ(例えば、<code><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch()</a></code>, <code><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> or <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/CSS/@font-face">fonts</a>)されたリソースをプリロードするとき、<code><link></code>要素に{{htmlattrxref( "crossorigin"、 "link")}}属性を設定する場合には特別な注意が必要です。</p>
<p dir="ltr" id="tw-target-text">上記のように、これが当てはまる興味深いケースの1つは、フォントファイルです。さまざまな理由により、これらは匿名モードのCORSを使用してフェッチする必要があります(<a href="https://drafts.csswg.org/css-fonts/#font-fetching-requirements">Font fetching requirements</a>参照)。</p>
<p>このケースを例として使用してみましょう。完全なサンプルソースコードは <a href="https://github.com/mdn/html-examples/tree/master/link-rel-preload/fonts">example source code on GitHub</a> (<a href="https://mdn.github.io/html-examples/link-rel-preload/fonts/">also see it live</a>):</p>
<pre class="brush: html notranslate"><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></pre>
<p dir="ltr" id="tw-target-text"><code>type</code>属性にMIMEタイプヒントを提供するだけでなく、プリロードのCORSモードが最終的なフォントリソースリクエストと一致することを確認するために、<code>crossorigin</code>属性も提供しています。</p>
<h2 id="Including_media" name="Including_media">media を含める</h2>
<p>One nice feature of <code><link></code> elements is their ability to accept {{htmlattrxref("media", "link")}} attributes. These can accept <a href="/en-US/docs/Web/CSS/@media#Media_types">media types</a> or full-blown <a href="/en-US/docs/Web/CSS/Media_Queries/Using_media_queries">media queries</a>, allowing you to do responsive preloading!</p>
<p>Let's look at an example (see it on GitHub — <a href="https://github.com/mdn/html-examples/tree/master/link-rel-preload/media">source code</a>, <a href="https://mdn.github.io/html-examples/link-rel-preload/media/">live example</a>):</p>
<pre class="brush: html notranslate"><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></pre>
<p>We include <code>media</code> attributes on our <code><link></code> 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 {{domxref("Window.matchMedia")}} / {{domxref("MediaQueryList")}} to do this (see <a href="/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries">Testing media queries</a> for more).</p>
<p>This makes it much more likely that the font will be available for the page render, cutting down on FOUT (flash of unstyled text).</p>
<p>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.</p>
<h2 id="Scripting_and_preloads" name="Scripting_and_preloads">スクリプトと先読み</h2>
<p>これらのプリロードに関するもう一つの良い点として、スクリプトを使って実行できることが挙げられます。例えば、ここでは {{domxref("HTMLLinkElement")}} インスタンスを作成し、それを DOM に適用させています。</p>
<pre class="brush: js notranslate"><code class="language-javascript"><span class="keyword token">var</span> preloadLink <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">createElement</span><span class="punctuation token">(</span><span class="string token">"link"</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
preloadLink<span class="punctuation token">.</span>href <span class="operator token">=</span> <span class="string token">"myscript.js"</span><span class="punctuation token">;</span>
preloadLink<span class="punctuation token">.</span>rel <span class="operator token">=</span> <span class="string token">"preload"</span><span class="punctuation token">;</span>
preloadLink<span class="punctuation token">.</span><span class="keyword token">as</span> <span class="operator token">=</span> <span class="string token">"script"</span><span class="punctuation token">;</span>
document<span class="punctuation token">.</span>head<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>preloadLink<span class="punctuation token">)</span><span class="punctuation token">;</span></code>
</pre>
<p>これは、ブラウザは <code>myscript.js</code> ファイルをプリロードしますが、実際はまだ使用されていません。これを使用するには、以下のようにします。</p>
<pre class="brush: js notranslate"><code class="language-javascript"><span class="keyword token">var</span> preloadedScript <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">createElement</span><span class="punctuation token">(</span><span class="string token">"script"</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
preloadedScript<span class="punctuation token">.</span>src <span class="operator token">=</span> <span class="string token">"myscript.js"</span><span class="punctuation token">;</span>
document<span class="punctuation token">.</span>body<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>preloadedScript<span class="punctuation token">)</span><span class="punctuation token">;</span>
</code></pre>
<p>これは、スクリプトをプリロードしたいが、必要なときまで実行を延期する場合に便利です。</p>
<h2 id="Other_resource_preloading_mechanisms" name="Other_resource_preloading_mechanisms">他のリソースの先読み機構</h2>
<p>Other preloading features exist, but none are quite as fit for purpose as <code><link rel="preload"></code>:</p>
<ul>
<li><code><link rel="prefetch"></code> has been supported in browsers for a long time, but it is intended for prefetching resources that will be used in the <strong><em>next</em></strong> 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 <code>prefetch</code> resources a lower priority than <code>preload</code> ones — the current page is more important than the next. See <a href="/en-US/docs/Web/HTTP/Link_prefetching_FAQ">Link prefetching FAQ</a> for more details.</li>
<li><code><link rel="prerender"></code> 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 <code>prerender</code> as a <a href="https://developers.google.com/web/updates/2018/07/nostate-prefetch">NoState prefetch</a> instead.</li>
<li><code><link rel="subresource"></code> {{non-standard_inline}} was supported in Chrome a while ago, and was intended to tackle the same issue as <code>preload</code>, but it had a problem: there was no way to work out a priority for the items (<code>as</code> didn't exist back then), so they all got fetched with fairly low priority.</li>
<li>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.</li>
</ul>
<h2 id="Specifications" name="Specifications">仕様書</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">仕様書</th>
<th scope="col">状態</th>
<th scope="col">備考</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('Preload','#x2.link-type-preload','preload')}}</td>
<td>{{Spec2('Preload')}}</td>
<td><code>preload</code> の詳細</td>
</tr>
<tr>
<td>{{SpecName('HTML WHATWG', '#link-type-preload', 'rel=preload')}}</td>
<td>{{Spec2('HTML WHATWG')}}</td>
<td><code>preload</code> の定義</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの対応</h2>
<p class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</p>
<p>{{Compat("html.elements.link.rel.preload")}}</p>
<h2 id="See_also" name="See_also">関連情報</h2>
<ul>
<li><a href="https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/">Preload: What Is It Good For?</a> by Yoav Weiss</li>
</ul>
<p>{{QuickLinksWithSubpages("/ja/docs/Web/HTML")}}</p>
|