rel=preconnect リソースヒントと rel=dns-prefetch リソースヒントについて、またそれらの使用方法について学びます。
ブラウザは、サーバーにリソースをリクエストする前に、接続を確立する必要があります。安全な接続を確立するには、次の 3 つのステップが必要です。
ドメイン名を検索して IP アドレスに解決します。
サーバーへの接続を設定します。
セキュリティを確保するために接続を暗号化します。
これらの各ステップで、ブラウザはサーバーにデータを送信し、サーバーはレスポンスを返します。出発地から目的地まで、そして目的地から出発地までを往復することを往復といいます。
ネットワークの状態によっては、1 回のラウンド トリップにかなりの時間がかかる場合があります。接続のセットアップ プロセスでは、最大 3 回のラウンドトリップが発生することがあります。最適化されていない場合はさらに多くのラウンドトリップが発生することもあります。
これらすべてを事前に処理することで、アプリケーションの速度を上げることができます。この記事では、2 つのリソースヒント(<link rel=preconnect>
と <link rel=dns-prefetch>
)を使用してこれを実現する方法について説明します。
rel=preconnect
との早期接続を確立する
最新のブラウザは、ページに必要な接続を可能な限り予測しようとしますが、すべての接続を正確に予測することはできません。幸い、ヒント(リソース 😉)を示すことができます。
<link>
に rel=preconnect
を追加すると、ページが別のドメインへの接続を確立しようとしていることと、プロセスをできるだけ早く開始する必要があることをブラウザに通知します。ブラウザがリクエストする時点でセットアップ プロセスがすでに完了しているため、リソースの読み込みが速くなります。
リソースヒントは、必須の指示ではないため、その名前が付けられています。望ましい動作についての情報は提供しますが、それを実行するかどうかはブラウザ次第です。接続の設定と維持には多くの作業が必要であるため、ブラウザは状況に応じてリソース ヒントを無視するか、部分的に実行することがあります。
以下のようにページに <link>
タグを追加するだけで、簡単にブラウザへの通知を行うことができます。
<link rel="preconnect" href="https://example.com">
重要なサードパーティ オリジンへの接続を早期に確立することで、読み込み時間を 100~500 ms 短縮できます。これらの数値は小さく見えるかもしれませんが、ユーザーがウェブページのパフォーマンスをどのように認識するかに影響します。
rel=preconnect
のユースケース
取得元はわかっているが、取得対象がわからない
依存関係がバージョニングされているために、特定の CDN からリソースをリクエストすることはわかっていても、リソースへの正確なパスがわからない場合があります。
もう一つの一般的なケースは、画像 CDN から画像を読み込む場合です。この場合、画像の正確なパスは、ユーザーのブラウザのメディアクエリやランタイム機能チェックによって異なります。
このような状況では、フェッチするリソースが重要であれば、サーバーに事前接続することで、できるだけ時間を節約することができます。ブラウザは、ページがリクエストするまでファイルをダウンロードしませんが、少なくとも事前に接続作業を処理できるので、ユーザーは数回のラウンドトリップを待機せずに済みます。
ストリーミング メディア
接続フェーズの時間を節約したいが、必ずしもコンテンツの取得をすぐに開始する必要がない別の例として、別の配信元からメディアをストリーミングする場合が挙げられます。
ストリーミングされたコンテンツをページが処理する方法によっては、スクリプトが読み込まれてストリームを処理する準備が整うまで待つほうがよいこともあります。プリコネクトを使用すると、フェッチを開始する準備が整ったら、待機時間を 1 回のラウンドトリップのみに短縮できます。
rel=preconnect
の実装方法
preconnect
を開始する方法の一つは、ドキュメントの <head>
に <link>
タグを追加することです。
<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 ルックアップの時間を節約します。通常、このステップは 20~120 ms ほどかかります。
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 アセットをすぐに検出可能にできない場合でも、fetchpriority
値が "high"
の preload
リンクを使用すると、ブラウザはリソースをできるだけ早く読み込むことができます。
これらのオプションのどちらも使用できない場合(ページの読み込みが進んでから正確なリソースが判明するため)、クロスオリジン リソースに preconnect
を使用して、リソースの遅延検出の影響を可能な限り軽減できます。
また、preconnect
は帯域幅の使用量の点で preload
よりも費用が低くなりますが、リスクがないわけではありません。過剰な preload
ヒントと同様に、過剰な preconnect
ヒントは、TLS 証明書が関係する場合でも帯域幅を消費します。帯域幅の競合が発生する可能性があるため、オリジンに事前接続しすぎないように注意してください。
まとめ
次の 2 つのリソースヒントは、すぐにサードパーティ ドメインからダウンロードすることはわかっていても、リソースの正確な URL がわからない場合に、ページの読み込み速度を改善する際に役立ちます。たとえば、JavaScript ライブラリ、画像、フォントなどを配信する CDN などです。制約に注意し、最も重要なリソースにのみ preconnect
を使用し、残りは dns-prefetch
に依存し、常に実際の影響を測定します。