読み込みの早いウェブサイトを作成するには、まず、ページの HTML に対するレスポンスをサーバーからタイムリーに受け取る必要があります。ブラウザのアドレスバーに URL を入力すると、ブラウザは GET
リクエストをサーバーに送信して取得します。ウェブページに対する最初のリクエストは、HTML リソースのリクエストです。HTML が最小限の遅延ですばやく到着できるようにすることは、重要なパフォーマンス目標です。
HTML に対する最初のリクエストでは、いくつかのステップを経て、それぞれのステップに時間がかかります。各ステップに費やす時間を短縮することで、最初のバイトまでの時間(TTFB)が短縮されます。ページの読み込み速度に関して、TTFB は唯一の指標ではありませんが、TTFB が高いと、Largest Contentful Paint(LCP)や First Contentful Paint(FCP)などの指標に指定された「良好」なしきい値に達することが困難になります。
リダイレクトの回数を減らす
リソースがリクエストされると、サーバーは永続的なリダイレクト(301 Moved Permanently
レスポンス)または一時的なリダイレクト(302 Found
レスポンス)のいずれかで、リダイレクトで応答する場合があります。
リダイレクトを行うと、リソースを取得するためにブラウザが新しい場所で追加の HTTP リクエストを行う必要があるため、ページの読み込み速度が低下します。リダイレクトには次の 2 種類があります。
- 配信元全体で発生する同一オリジン リダイレクト。このようなリダイレクトの管理ロジックはウェブサーバー上に完全に存在するため、これらの種類のリダイレクトは完全に制御できます。
- 別のオリジンによって開始されたクロスオリジン リダイレクト。通常、この種のリダイレクトは制御できません。
クロスオリジン リダイレクトは、広告や URL 短縮サービス、その他のサードパーティ サービスでよく使用されます。クロスオリジン リダイレクトは自分で管理することはできませんが、複数のリダイレクトを避けることが必要になる場合もあります。たとえば、HTTP ページにリンクされている広告から HTTPS ページにリダイレクトされる場合や、クロスオリジン リダイレクトが元のオリジンに到着した後、同一オリジン リダイレクトがトリガーされる場合などです。
HTML レスポンスをキャッシュに保存する
HTML レスポンスのキャッシュは困難です。レスポンスには、CSS、JavaScript、画像、その他のリソースタイプなど、他の重要なリソースへのリンクが含まれることがあるためです。これらのリソースのファイル名には、ファイルの内容に応じて変化する一意のフィンガープリントを含めることができます。つまり、キャッシュ内の HTML ドキュメントには古いサブリソースへの参照が含まれているため、デプロイ後に古くなってしまう可能性があります。
ただし、キャッシュ保存を行わないのではなく、キャッシュの有効期間が短いと、CDN でリソースをキャッシュに保存できる、送信元サーバーから提供されるリクエストの数を削減できる、ブラウザでリソースを再ダウンロードせずに再検証できるなどのメリットがあります。このアプローチは、どのコンテキストでも変化しない静的コンテンツに最適です。また、リソースをキャッシュに保存する適切な時間は、適切と考える数分に設定できます。静的 HTML リソースの場合は 5 分間を確保することをおすすめします。これにより、定期的な更新が気づかれないようにすることができます。
ページの HTML コンテンツがなんらかの方法で(認証済みユーザー用などで)パーソナライズされている場合、セキュリティや鮮度などのさまざまな懸念から、コンテンツをキャッシュに保存する必要はほとんどありません。HTML レスポンスがユーザーのブラウザによってキャッシュに保存されている場合、キャッシュを無効にすることはできません。したがって、そのような場合は HTML を完全にキャッシュに保存しないことをおすすめします。
HTML をキャッシュに保存する場合は、レスポンス ヘッダー ETag
または Last-Modified
を使用することをおすすめします。ETag
(エンティティ タグとも呼ばれます)ヘッダーは、リクエストされたリソースを一意に表す識別子です。多くの場合、リソースのコンテンツのハッシュを使用します。
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
リソースが変更されるたびに、新しい ETag
値を生成する必要があります。後続のリクエストで、ブラウザは If-None-Match
リクエスト ヘッダーを介して ETag
値を送信します。サーバー上の ETag
がブラウザから送信されたものと一致する場合、サーバーは 304 Not Modified
レスポンスで応答し、ブラウザはキャッシュのリソースを使用します。この場合もネットワーク レイテンシが発生しますが、304 Not Modified
レスポンスは HTML リソース全体よりもはるかに小さくなります。
ただし、リソースの更新頻度の再検証に伴うネットワーク レイテンシには、やはりデメリットがあります。ウェブ開発の他の多くの側面と同様に、トレードオフや妥協は避けられません。この方法で HTML をキャッシュに保存することに意味があるか、HTML コンテンツをまったくキャッシュに保存せずに安全に行うのが最善かは、デベロッパーが判断します。
サーバーの応答時間を測定する
レスポンスがキャッシュに保存されていない場合、サーバーのレスポンス時間は、ホスティング プロバイダとバックエンド アプリケーション スタックによって大きく異なります。データベースからデータを取得するなど、動的に生成されるレスポンスを提供するウェブページは、バックエンドでのコンピューティング時間がそれほどかからずにすぐに配信できる静的ウェブページよりも、TTFB が高くなる可能性があります。読み込みスピナーを表示し、クライアントサイドですべてのデータを取得すると、より予測可能なサーバーサイドの環境から、予測不可能なクライアントサイドの環境へと作業が移ります。通常、クライアントサイドの作業を最小限に抑えることで、ユーザー中心の指標が改善されます。
フィールドの TTFB が遅い場合、Server-Timing
レスポンス ヘッダーを使用して、サーバーでの経過時間に関する情報を公開できます。
Server-Timing: auth;dur=55.5, db;dur=220
Server-Timing
ヘッダーの値には、複数の指標と各指標の期間を含めることができます。このデータは、Navigation Timing API を使用して現場のユーザーから収集され、ユーザーに遅延が発生していないかどうか分析できます。上記のコード スニペットでは、レスポンス ヘッダーに 2 つのタイミングが含まれています。
- ユーザーの認証にかかった時間(
auth
)。所要時間は 55.5 ミリ秒です。 - データベース アクセス時間(
db
)。所要時間は 220 ミリ秒です。
また、ホスティング インフラストラクチャを見直し、ウェブサイトが受信しているトラフィックを処理するのに十分なリソースがあることを確認することもおすすめします。共有ホスティング プロバイダは、しばしば高い TTFB の影響を受けやすく、より迅速な応答時間を提供する専用ソリューションの方がコストが高くなる可能性があります。
圧縮
HTML、JavaScript、CSS、SVG 画像などのテキストベースのレスポンスは、ダウンロード時間を短縮するために圧縮して、ネットワーク経由の転送サイズを小さくする必要があります。最も広く使用されている圧縮アルゴリズムは gzip と Brotli です。Brotli は gzip よりも約 15 ~ 20% 改善されています。
圧縮は、ほとんどのウェブ ホスティング プロバイダによって自動的に設定されますが、圧縮設定をご自身で構成または調整する場合は、以下の重要な点を考慮してください。
- 可能な限り Brotli を使用する。前述のように、Brotli は gzip よりもかなり改善されており、Brotli はすべての主要なブラウザでサポートされています。可能な限り Brotli を使用しますが、ウェブサイトを従来のブラウザで多くのユーザーが使用している場合は、gzip をフォールバックとして使用してください。これは、圧縮なしよりも圧縮の方が優れているためです。
- ファイルサイズは重要です。1 KiB 未満の非常に小さいリソースは圧縮率にあまり優れません。まったく圧縮されないこともあります。どのタイプのデータ圧縮も、圧縮可能なデータが大量にあるかどうかによって、圧縮アルゴリズムが処理できるデータの量が増えます。ファイルが大きければ大きいほど、圧縮率は向上します。ただし、圧縮効率が高いからといって、大量のリソースを送ってはいけません。JavaScript や CSS などの大きなリソースの場合、ブラウザによる圧縮解除後は解析と評価に非常に時間がかかります。また、わずかな変更であっても、変更によってファイル ハッシュが異なるため、頻繁に変更される場合があります。
- 動的圧縮と静的圧縮の違いを理解する。動的圧縮と静的圧縮では、リソースを圧縮するタイミングのアプローチが異なります。動的圧縮ではリソースが圧縮されます。これはリソースがリクエストされたとき、場合によってはリクエストされるたびに圧縮されます。一方、静的圧縮ではファイルが事前に圧縮されるため、リクエスト時に圧縮を実行する必要がありません。静的圧縮では、圧縮自体に伴うレイテンシが取り除かれ、動的圧縮の場合にサーバーの応答時間が長くなる可能性があります。静的リソース(JavaScript、CSS、SVG 画像など)は静的に圧縮する必要がありますが、HTML リソース(特に、認証されたユーザー用に動的に生成される場合)は動的に圧縮する必要があります。
自力で圧縮を行うのは簡単ではありませんが、通常は、次のセクションで説明するコンテンツ配信ネットワーク(CDN)で処理するのが最善です。ただし、これらのコンセプトを知ることは、ホスティング プロバイダが圧縮を適切に使用しているかどうかを見分けるのに役立ちます。そうした知識があれば、圧縮設定を改善して、ウェブサイトが最大限にメリットを享受できるようになります。
コンテンツ配信ネットワーク(CDN)
コンテンツ配信ネットワーク(CDN)は、配信元のサーバーのリソースをキャッシュに保存し、物理的にユーザーに近いエッジサーバーから提供するサーバーの分散ネットワークです。ユーザーと物理的に近接することでラウンドトリップ時間(RTT)が短縮され、HTTP/2 や HTTP/3、キャッシュ、圧縮などの最適化により、CDN は配信元サーバーから取得するよりも迅速にコンテンツを配信できます。CDN を利用すると、場合によってはウェブサイトの TTFB を大幅に改善できます。
理解度テスト
完全に制御できるリダイレクトのタイプは次のうちどれですか。
Server-Timing
ヘッダーには複数の指標を含めることができます。
エンドユーザーに物理的に最も近い可能性があるのは、どのタイプのサーバーか。
次のトピック: クリティカル パスを理解する
ここまでで、ウェブサイトの HTML のパフォーマンスに関する考慮事項についてご理解いただけたと思います。これより、できるだけ速く読み込めることを確認したほうがよいでしょう。しかし、これはウェブ パフォーマンスについて学ぶ始まりにすぎません。次に、クリティカル レンダリング パスの背後にある理論について説明します。このモジュールでは、レンダリング ブロック リソースや解析ブロック リソースなどの重要なコンセプトと、ページの最初のレンダリングをできるだけ早くブラウザで取得する際にそれらが果たす役割について説明します。