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

リソースの読み込みの最適化に関する前のモジュールでは、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 よりも適切なツールもあります。特に、ユーザーがたどる可能性が高い他のウェブサイトに移動するリンクの場合は、リソースヒントを使用することをおすすめします。dnstradamus は、JavaScript を使用してこの処理を自動的に行うツールの 1 つで、他のウェブサイトへのリンクがユーザーのビューにスクロールされたときに、Intersection Observer API を使用して現在のページの HTML に dns-prefetch ヒントを挿入します。

preload

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

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

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

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> 要素、リソースヒントに関するパフォーマンスに関する一般的な考慮事項について、すでにかなりの知識が身に付けてきたことでしょう。ただし、一般的にページが読み込まれるさまざまなリソースタイプに固有の追加の最適化があります。次のモジュールでは、画像のパフォーマンスについて説明します。モジュールでは、ユーザーのデバイスに関係なく、ウェブサイトの画像を可能な限り速く読み込むことができます。