リソースヒントを使用してブラウザをサポートする

リソースの読み込みの最適化に関する前回のモジュールでは、CSS や JavaScript などのさまざまなページリソースがページ読み込み速度に与える影響と、リソースとその配信を最適化してページのレンダリングを高速化する方法を学習しました。これは、リソース読み込みのより高度な側面に移行するのに最適なタイミングであり、ブラウザがリソースヒントを使用してリソースの読み込みを高速化するのに役立ちます。

リソースヒントを使用すると、リソースの読み込み方法と優先順位付け方法をブラウザに伝えることで、デベロッパーはページの読み込み時間をさらに最適化できます。preconnectdns-prefetch などのリソースヒントの初期セットが最初に導入されました。しかし、時間の経過とともに、preload と Fetch Priority API が徐々に追加され、機能が追加されています。

リソースヒントは、読み込みパフォーマンスを向上させる可能性のある特定のアクションを前もって実行するようブラウザに指示します。リソースヒントは、初期の DNS ルックアップの実行、事前のサーバーに接続する、ブラウザが通常検出する前にリソースを取得するなどのアクションを実行できます。

リソースヒントは、HTML で指定することも(ほとんどの場合は <head> 要素の初期で)指定することも、HTTP ヘッダーとして設定することもできます。このモジュールの範囲では、preconnectdns-prefetchpreload と、prefetch が提供する投機的取得動作について説明します。

preconnect

preconnect ヒントは、重要なリソースを取得する場所から別のオリジンへの接続を確立するために使用されます。たとえば、CDN やその他のクロスオリジンで画像やアセットをホストしている可能性があります。

<link rel="preconnect" href="https://example.com">

preconnect を使用すると、ブラウザはごく近い将来に特定のクロスオリジン サーバーに接続する予定であり、ブラウザはできるだけ早く(理想的には HTML パーサーまたはプリロード スキャナによる接続を待つ前に)その接続を開くことが想定されます。

ページに大量のクロスオリジン リソースがある場合は、現在のページにとって最も重要なリソースに preconnect を使用します。

Chrome DevTools のネットワーク パネルにあるリソースの接続タイミングのスクリーンショット。接続の設定には、停滞時間、プロキシ ネゴシエーション、DNS ルックアップ、接続設定、TLS ネゴシエーションが含まれます。
Chrome DevTools のネットワーク パネルに表示された接続タイミングの可視化。赤い枠内のタイミングは、クロスオリジン サーバーとの接続を確立するタイミングです。preconnect では、クロスオリジン リソースの検出時点ではなく、より早く接続を確立することで緩和できます。

preconnect の一般的なユースケースは Google Fonts です。Google Fonts では、@font-face 宣言を提供する https://fonts.googleapis.com ドメインと、フォント ファイルを提供する https://fonts.gstatic.com ドメインに preconnect することをおすすめします。

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

crossorigin 属性は、クロスオリジン リソース シェアリング(CORS)を使用してリソースを取得する必要があるかどうかを示すために使用します。preconnect ヒントを使用する場合、送信元からダウンロードされるリソースが CORS(フォント ファイルなど)を使用している場合は、preconnect ヒントに crossorigin 属性を追加する必要があります。

dns-prefetch

クロスオリジン サーバーへの接続を早期に開始することで、初期ページの読み込み時間を大幅に短縮できますが、多数のクロスオリジン サーバーへの接続を一度に確立することは妥当でない、または実現できない可能性があります。preconnect を過剰に使用することが懸念される場合は、dns-prefetch ヒントを使用してコストを大幅に削減できます。

dns-prefetch はその名前から、クロスオリジン サーバーへの接続を確立するのではなく、事前に DNS ルックアップを実行するだけです。DNS ルックアップは、ドメイン名が基盤となる IP アドレスに解決されたときに行われます。デバイスレベルとネットワーク レベルで DNS キャッシュのレイヤを作成することで、通常はこのプロセスを高速化できますが、それでもある程度の時間がかかります。

<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://fonts.gstatic.com">

DNS ルックアップはかなり安価です。また、コストが比較的小さいため、preconnect よりも適切なツールである場合があります。特に、ユーザーがたどる可能性が高い他のウェブサイトに移動するリンクでは、リソースヒントの使用が望ましい場合があります。こうしたツールの 1 つが dnstradamus で、JavaScript を使用してこの処理を自動的に行います。他のウェブサイトへのリンクがスクロールされたときに、Intersection Observer API を使用して現在のページの HTML に dns-prefetch ヒントを挿入します。

preload

preload ディレクティブは、ページのレンダリングに必要なリソースの早期リクエストを開始するために使用されます。

<link rel="preload" href="/lcp-image.jpg" as="image">

preload ディレクティブは、後で検出される重要なリソースに限定する必要があります。最も一般的なユースケースは、フォント ファイル、@import 宣言によって取得される CSS ファイル、Largest Contentful Paint(LCP)の候補となる CSS background-image リソースです。この場合、リソースは外部リソースで参照されているため、これらのファイルはプリロード スキャナで検出されません。

preconnect と同様に、フォントなどの CORS リソースをプリロードする場合、preload ディレクティブで crossorigin 属性が必要になります。crossorigin 属性を追加しない場合、または非 CORS リクエスト用に追加しない場合、リソースはブラウザによって 2 回ダウンロードされ、他のリソースに費やした可能性のある帯域幅が無駄になります。

<link rel="preload" href="/font.woff2" as="font" crossorigin>

上記の HTML スニペットでは、/font.woff2 が同じドメイン上にある場合でも、CORS リクエストを使用して /font.woff2 をプリロードするようにブラウザに指示されています。

prefetch

prefetch ディレクティブは、今後のナビゲーションに使用される可能性が高いリソースに対して優先度の低いリクエストを開始するために使用されます。

<link rel="prefetch" href="/next-page.css" as="style">

このディレクティブの形式は preload ディレクティブとほぼ同じですが、"prefetch" という値を使用するのは <link> 要素の rel 属性のみです。ただし、preload ディレクティブとは異なり、prefetch は、将来のナビゲーションのためにリソースの取得を開始する(または発生しない可能性あり)という点で、基本的には投機的です。

prefetch が有益な場合もあります。たとえば、ほとんどのユーザーが完了するまでたどるユーザーフローがウェブサイト上で特定されている場合、そのページのレンダリングに不可欠なリソースの prefetch は、読み込み時間の短縮に役立ちます。

Fetch Priority API

fetchpriority 属性で Fetch Priority API を使用すると、リソースの優先度を上げることができます。この属性は、<link> 要素、<img> 要素、<script> 要素とともに使用できます。

<div class="gallery">
  <div class="poster">
    <img src="img/poster-1.jpg" fetchpriority="high">
  </div>
  <div class="thumbnails">
    <img src="img/thumbnail-2.jpg" fetchpriority="low">
    <img src="img/thumbnail-3.jpg" fetchpriority="low">
    <img src="img/thumbnail-4.jpg" fetchpriority="low">
  </div>
</div>

デフォルトでは、画像は低い優先度で取得されます。レイアウト後、画像が最初のビューポート内にあることが判明した場合は、優先度がに引き上げられます。上記の HTML スニペットで、fetchpriority は即座に大きい LCP 画像を優先度「高」でダウンロードし、重要度の低いサムネイル画像は低い優先度でダウンロードするようブラウザに指示します。

最新のブラウザは、2 つのフェーズでリソースを読み込みます。最初のフェーズは重要なリソース用に予約されており、すべてのブロッキング スクリプトがダウンロードされて実行されると終了します。このフェーズでは、優先度がのリソースのダウンロードが遅れる可能性があります。fetchpriority="high" を使用すると、リソースの優先度が上がり、最初のフェーズでブラウザがリソースをダウンロードできるようになります。

リソースヒントのデモ

知識を試す

preconnect リソースヒントの機能

クロスオリジン サーバーへの接続(DNS ルックアップや、ブラウザが検出する前に接続と TLS ネゴシエーションなど)を開きます。
正解です。
クロスオリジン サーバーの DNS ルックアップのみを実行します。
もう一度お試しください。

Fetch Priority API でできることは何ですか。

現在のページの HTML をダウンロードする優先度を指定します。
もう一度お試しください。
<link> 要素、<img> 要素、<script> 要素の相対的な優先度を指定します。
正解です。

prefetch ヒントを使用するのは、どのような場合ですか。

ユーザーが今後実際に必要になるかどうかにかかわらず、ユーザーが必要とするあらゆるリソースまたはページ。
もう一度お試しください。
プリフェッチを予定しているリソースやページがユーザーによって必要であるという確信が強い場合。
正解です。
ユーザーがデータ使用量の削減を明示的に希望していない場合。
正解です。

次のトピック: 画像のパフォーマンス

ページの HTML、<head> 要素、リソースヒントに関する、一般的なパフォーマンスに関する考慮事項についてすでにご理解いただけたと思います。ただし、ページでよく読み込まれるさまざまなリソースタイプに固有の最適化があります。次のモジュールでは、画像のパフォーマンスについて説明します。このモジュールでは、ユーザーのデバイスに関係なく、ウェブサイトの画像を可能な限り速く読み込む方法を紹介します。