rel=preconnect と rel=dns-prefetch のリソースヒントとその使用方法について説明します。
ブラウザは、サーバーにリソースをリクエストする前に、接続を確立する必要があります。安全な接続を確立するには、次の 3 つのステップが必要です。
ドメイン名を検索して、IP アドレスに解決します。
サーバーへの接続を設定します。
セキュリティのため接続を暗号化します。
これらの各ステップで、ブラウザからサーバーにデータが送信され、サーバーからレスポンスが返されます。出発地から目的地まで、そしてその場所に戻るまでの移動を往復と呼びます。
ネットワークの状態によっては、1 回のラウンド トリップでかなりの時間がかかることがあります。接続設定プロセスには最大 3 回のラウンド トリップが含まれることがあり、最適化されていない場合にはそれ以上のラウンド トリップが発生します。
これらすべてを事前に行うことで、アプリケーションの処理速度が大幅に向上します。この投稿では、2 つのリソースヒント <link rel=preconnect>
と <link rel=dns-prefetch>
を使用してこれを実現する方法について説明します。
rel=preconnect
との早期接続を確立
最新のブラウザは、ページに必要な接続を可能な限り予測しようとしますが、すべてを確実に予測することはできません。幸いなことに、(リソース 😉?)ヒントを与えることができます。
rel=preconnect
を <link>
に追加すると、ページが別のドメインへの接続を確立しようとしていることと、プロセスをできるだけ早く開始する必要があることをブラウザに通知します。ブラウザが要求する時点で設定プロセスはすでに完了しているため、リソースの読み込みが速くなります。
リソースヒントは必須の手順ではないため、名前が付けられます。実行する処理に関する情報を提供しますが、実行するかどうかは最終的にブラウザが決定します。接続を設定して開いたままにするのは大変な作業のため、ブラウザは状況に応じてリソースヒントを無視するか、部分的に実行するかを選択します。
ページに <link>
タグを追加するだけで、簡単にブラウザに通知できます。
<link rel="preconnect" href="https://example.com">
重要なサードパーティの送信元への早期接続を確立することで、読み込み時間を 100 ~ 500 ミリ秒短縮できます。これらの数値は小さく見えるかもしれませんが、ウェブページのパフォーマンスに対するユーザーの感じ方には違いがあります。
rel=preconnect
のユースケース
どこから取得するかはわかっているが、何を取得するかはわからない
バージョニングされた依存関係により、特定の CDN からのリソースをリクエストすることはわかっているものの、その正確なパスはわからない場合があります。
もう 1 つの一般的なケースは、画像 CDN からの画像の読み込みです。画像の正確なパスは、ユーザーのブラウザのメディアクエリやランタイム機能チェックによって異なります。
このような場合、取得するリソースが重要な場合は、サーバーに事前に接続することで、できる限り時間を節約する必要があります。ブラウザは、ページから要求されるまでファイルをダウンロードしませんが、少なくとも前もって接続処理を処理できるため、ユーザーは複数回のラウンド トリップを待つ必要がなくなります。
ストリーミング メディア
接続フェーズの時間を節約したいが、コンテンツの取得をすぐに始める必要はないもう 1 つの例としては、別のオリジンからメディアをストリーミングする場合が挙げられます。
ページでストリーミング コンテンツがどのように処理されるかに応じて、スクリプトが読み込まれてストリームを処理する準備が整うまで待つことをおすすめします。事前接続しておくと、フェッチを開始する準備ができたら、待ち時間を 1 回の往復に短縮できます。
rel=preconnect
の実装方法
preconnect
を開始する方法の 1 つは、<link>
タグをドキュメントの <head>
に追加することです。
<head>
<link rel="preconnect" href="https://example.com">
</head>
事前接続は、オリジン ドメイン以外のドメインでのみ有効であるため、サイトには使用しないでください。
Link
HTTP ヘッダーを使用して事前接続を開始することもできます。
Link: <https://example.com/>; rel=preconnect
フォントなど、一部のリソースタイプは匿名モードで読み込まれます。そのような場合は、preconnect
ヒントを指定して crossorigin
属性を設定する必要があります。
<link rel="preconnect" href="https://example.com/ComicSans" crossorigin>
crossorigin
属性を省略すると、ブラウザは DNS ルックアップのみを実行します。
rel=dns-prefetch
でドメイン名を早期に解決する
サイトは名前で記憶されますが、サーバーは IP アドレスで記憶します。これが、ドメイン ネーム システム(DNS)が存在する理由です。ブラウザは DNS を使用してサイト名を IP アドレスに変換します。このプロセス(ドメイン名解決)は、接続を確立するための最初のステップです。
ページから多数のサードパーティのドメインに接続する必要がある場合は、それらをすべて事前に接続すると逆効果になります。preconnect
ヒントは、最も重要な接続にのみ使用するのが最適です。残りはすべて <link rel=dns-prefetch>
を使用して、最初のステップである DNS ルックアップの時間を節約します。DNS ルックアップには通常 20 ~ 120 ミリ秒ほどかかります。
DNS 解決は、preconnect
と同様に、ドキュメントの <head>
に <link>
タグを追加して開始します。
<link rel="dns-prefetch" href="http://example.com">
dns-prefetch
のブラウザ サポートは、preconnect
サポートとは若干異なるため、dns-prefetch
は preconnect
をサポートしていないブラウザのフォールバックとして機能します。
<link rel="preconnect" href="http://example.com"> <link rel="dns-prefetch" href="http://example.com">
<link rel="preconnect dns-prefetch" href="http://example.com">
Largest Contentful Paint(LCP)への影響
dns-prefetch
と preconnect
を使用すると、サイトは別のオリジンへの接続時間を短縮できます。最終的な目標は、別の送信元からリソースを読み込む時間を可能な限り最小限に抑えることです。
Largest Contentful Paint(LCP)に関しては、リソースがすぐに見つかる方がよいでしょう。LCP の候補はユーザー エクスペリエンスの重要な要素であるためです。LCP リソースの fetchpriority
値を "high"
にすると、このアセットの重要性をブラウザに通知して早期に取得できるようにすることで、この問題をさらに改善できます。
LCP アセットをすぐに検出できるようにできない場合でも、preload
リンク(fetchpriority
の値が "high"
)を使用すると、ブラウザはできるだけ早くリソースを読み込むことができます。
正確なリソースはページ読み込みの後半までわからないため、どちらのオプションも利用できない場合は、クロスオリジン リソースで preconnect
を使用して、リソースの検出が遅れる影響を可能な限り減らすことができます。
さらに、preconnect
は帯域幅の使用量の点で preload
よりも低コストですが、リスクがないわけではありません。過剰な preload
ヒントの場合と同様に、過剰な preconnect
ヒントを使用すると、TLS 証明書が関係する帯域幅を依然として消費します。事前接続のオリジンが多すぎると帯域幅の競合が発生する可能性があるため、注意してください。
まとめ
これら 2 つのリソースヒントは、近いうちにサードパーティ ドメインから何かをダウンロードすることがわかっているが、リソースの正確な URL がわからない場合に、ページの読み込み速度を向上させるのに役立ちます。たとえば、JavaScript ライブラリ、画像、フォントを配信する CDN が挙げられます。制約に注意し、最も重要なリソースにのみ preconnect
を使用し、それ以外は dns-prefetch
を使用して、常に実際の影響を測定します。