Time to First Byte 指標を最適化する方法を学びます。
最初のバイトまでの時間(TTFB)は、First Contentful Paint(FCP)や Largest Contentful Paint(LCP)など、他のすべての有意なユーザー エクスペリエンス指標に先立つ、ウェブ パフォーマンスの基本指標です。つまり、TTFB 値が高いほど、それに続く指標に時間がかかります。
サーバーがナビゲーション リクエストに十分迅速に応答し、75 パーセンタイルのユーザーが「良好」のしきい値内の FCP を体験できるようにすることをおすすめします。大まかな目安として、ほとんどのサイトでは TTFB を 0.8 秒以下に抑える必要があります。
TTFB を測定する方法
TTFB を最適化する前に、TTFB がウェブサイトのユーザーにどのように影響するかを観察する必要があります。TTFB はリダイレクトの影響を受けるため、TTFB を測定する主なソースとしてフィールドデータに依存する必要があります。一方、ラボベースのツールは最終的な URL を使用して測定されることが多いため、この追加の遅延が測定されません。
PageSpeed Insights は、Chrome ユーザー エクスペリエンス レポートで利用可能な、一般公開されているウェブサイトのフィールド データとラボデータの両方を取得する方法の一つです。
実際のユーザーの TTFB は、上部の [実際のユーザーの環境で評価する] セクションに表示されます。
ラボデータの場合、TTFB のサブセットがサーバー レスポンス時間の監査に表示されます。
フィールドとラボの両方で TTFB を測定する方法について詳しくは、TTFB 指標のページをご覧ください。
フィールドとラボの TTFB の違いを理解する
ラボとフィールドの TTFB は、さまざまな理由で異なる場合があります。異なる場合は、ラボデータを効果的に使用してユーザー エクスペリエンスを改善できるように、その理由を把握することが重要です。
ラボの TTFB がフィールドの TTFB よりもはるかに大きい場合は、ラボ環境が一般的なユーザー エクスペリエンスよりも制約されていることを示します。ラボの結果と推奨事項は有効である可能性が高いため、これは必ずしも問題ではありませんが、影響と改善が誇張される可能性があります。
フィールドの TTFB がラボの TTFB よりも大幅に大きい場合は、サーバーサイド キャッシュの使用、リダイレクト、ネットワークの違いなど、ラボの実行中に明らかでない問題があることを示します。この場合、ラボの結果と推奨事項は、主な問題の 1 つが検出されない可能性があるため、あまり役に立たない可能性があります。
サーバーサイド キャッシュがラボの TTFB に影響しているかどうかを確認するには、あまり使用されていないページをテストするか、別の URL パラメータを使用してキャッシュに保存されていないコンテンツを取得し、TTFB がフィールドの TTFB と一致しているかどうかを確認します。また、特定の URL パラメータを使用してサーバーサイド キャッシュをバイパスすることもできます。キャッシュに保存されたコンテンツのセクションをご覧ください。
リダイレクトとネットワークの違いについては、サイトへのトラフィックの発生方法と発生元を分析することで、問題の可能性を診断できます。
Server-Timing
を使用して現場で TTFB の長さをデバッグする
Server-Timing
レスポンス ヘッダーは、アプリケーション バックエンドで使用して、レイテンシの増加につながる可能性がある個別のバックエンド プロセスを測定できます。ヘッダー値の構造は柔軟で、少なくとも定義したハンドルを受け入れます。省略可能な値には、時間の値(dur
を使用)と、人間が読める説明(desc
を使用)があります。
Serving-Timing
は多くのアプリケーション バックエンド プロセスの測定に使用できますが、特に注意が必要なプロセスもあります。
- データベース クエリ
- サーバーサイド レンダリング時間(該当する場合)
- ディスク シーク
- エッジサーバー キャッシュのヒットまたはミス(CDN を使用している場合)
Server-Timing
エントリのすべての部分はコロンで区切られ、複数のエントリはカンマで区切ることができます。
// Two metrics with descriptions and values
Server-Timing: db;desc="Database";dur=121.3, ssr;desc="Server-side Rendering";dur=212.2
ヘッダーは、アプリケーション バックエンドの任意の言語を使用して設定できます。たとえば、PHP では次のようにヘッダーを設定できます。
<?php
// Get a high-resolution timestamp before
// the database query is performed:
$dbReadStartTime = hrtime(true);
// Perform a database query and get results...
// ...
// Get a high-resolution timestamp after
// the database query is performed:
$dbReadEndTime = hrtime(true);
// Get the total time, converting nanoseconds to
// milliseconds (or whatever granularity you need):
$dbReadTotalTime = ($dbReadEndTime - $dbReadStartTime) / 1e+6;
// Set the Server-Timing header:
header('Server-Timing: db;desc="Database";dur=' . $dbReadTotalTime);
?>
このヘッダーが設定されると、ラボと現場の両方で使用できる情報が表示されます。
フィールドでは、Server-Timing
レスポンス ヘッダーが設定されているページは、Navigation Timing API の serverTiming
プロパティに入力されます。
// Get the serverTiming entry for the first navigation request:
performance.getEntries('navigation')[0].serverTiming.forEach(entry => {
// Log the server timing data:
console.log(entry.name, entry.description, entry.duration);
});
ラボでは、Server-Timing
レスポンス ヘッダーのデータが、Chrome DevTools の [Network] タブのタイミング パネルに表示されます。
Chrome DevTools の [ネットワーク] タブに表示された Server-Timing
レスポンス ヘッダー。ここで、Server-Timing
は、リソースのリクエストが CDN キャッシュにヒットしたかどうか、およびリクエストが CDN のエッジサーバーと送信元にヒットするまでの時間を測定するために使用されます。
利用可能なデータを分析して、TTFB に問題があることが判明したら、問題の解決に進みます。
TTFB を最適化する方法
TTFB の最適化で最も難しいのは、ウェブのフロントエンド スタックは常に HTML、CSS、JavaScript であるのに対し、バックエンド スタックは大きく異なる可能性があることです。バックエンド スタックとデータベース プロダクトは数多くあり、それぞれに独自の最適化手法があります。そのため、このガイドでは、スタック固有のガイダンスにのみ焦点を当てるのではなく、ほとんどのアーキテクチャに適用される内容に焦点を当てます。
プラットフォーム固有のガイダンス
ウェブサイトに使用するプラットフォームは、TTFB に大きな影響を与える可能性があります。たとえば、WordPress のパフォーマンスは、プラグインの数や品質、使用されているテーマによって影響を受けます。他のプラットフォームも、プラットフォームがカスタマイズされると同様の影響を受けます。この投稿で説明する一般的なパフォーマンスに関するアドバイスに加えて、ベンダー固有のアドバイスについては、ご利用のプラットフォームのドキュメントを参照してください。サーバー レスポンス時間を短縮するための Lighthouse 監査には、スタック固有のガイダンスも一部含まれています。
ホスティング、ホスティング、ホスティング
他の最適化方法を検討する前に、まずホスティングを検討する必要があります。具体的なガイダンスをここで提供することはできませんが、一般的な目安としては、ウェブサイトのホストが送信されるトラフィックを処理できる状態にしておくことが挙げられます。
通常、共有ホスティングは遅くなります。主に静的ファイルを提供する小規模な個人ウェブサイトを運営している場合は、この程度で問題ないと思われます。後述する最適化手法のいくつかは、TTFB を可能な限り短縮するのに役立ちます。
ただし、パーソナライズ、データベース クエリ、その他のサーバーサイドの負荷の高いオペレーションを伴う、多くのユーザーが使用する大規模なアプリケーションを運用している場合は、フィールドでの TTFB を短縮するために、ホスティング サービスの選択が重要になります。
ホスティング プロバイダを選択する際は、次の点に注意してください。
- アプリケーション インスタンスに割り当てられているメモリ量はどのくらいですか?アプリケーションのメモリが不足すると、スラッシングが発生し、できるだけ速くページを提供するのに苦労します。
- ホスティング プロバイダはバックエンド スタックを最新の状態に保っていますか?アプリケーション バックエンド言語、HTTP 実装、データベース ソフトウェアの新しいバージョンがリリースされると、そのソフトウェアのパフォーマンスは時間とともに向上します。このような重要なメンテナンスに優先順位を付けるホスティング プロバイダと提携することが重要です。
- アプリケーションに非常に具体的な要件があり、サーバー構成ファイルに最下位レベルでアクセスする必要がある場合は、独自のアプリケーション インスタンスのバックエンドをカスタマイズするのが適切かどうかを尋ねます。
こうした処理は多くのホスティング プロバイダが代行してくれますが、専用ホスティング プロバイダでも TTFB 値が長くなるようであれば、最適なユーザー エクスペリエンスを提供できるよう、現在のホスティング プロバイダの機能を再評価する必要が生じている可能性があります。
コンテンツ配信ネットワーク(CDN)を使用する
CDN の使用はよく議論されるトピックですが、その理由は明らかです。アプリケーション バックエンドが非常に最適化されている場合でも、オリジン サーバーから遠く離れたユーザーは、フィールドで TTFB が高くなる可能性があります。
CDN は、ユーザーに物理的に近いサーバーにリソースをキャッシュする分散サーバー ネットワークを使用して、ユーザーと配信元サーバーの距離の問題を解決します。これらのサーバーはエッジサーバーと呼ばれます。
CDN プロバイダは、エッジ サーバー以外のメリットも提供できます。
- 通常、CDN プロバイダは非常に高速な DNS 解決時間を提供します。
- CDN は、HTTP/2 や HTTP/3 などの最新のプロトコルを使用してエッジサーバーからコンテンツを配信します。
- 特に HTTP/3 は、UDP プロトコルを使用して、HTTP/2 が依存する TCP に存在するヘッドオブライン ブロッキングの問題を解決します。
- CDN は最新バージョンの TLS も提供しているため、TLS ネゴシエーション時間に関連するレイテンシを短縮できます。特に TLS 1.3 は、TLS ネゴシエーションをできるだけ短くするように設計されています。
- 一部の CDN プロバイダは、「エッジ ワーカー」と呼ばれる機能を提供しています。これは、Service Worker API に似た API を使用して、リクエストをインターセプトしたり、エッジ キャッシュ内のレスポンスをプログラムで管理したり、レスポンスを完全に書き換えたりします。
- CDN プロバイダは、圧縮の最適化に非常に優れています。圧縮は自分で正しく行うのが難しいため、動的に生成されたマークアップをその場で圧縮する必要がある場合、レスポンスが遅くなることがあります。
- また、CDN プロバイダは、静的リソースの圧縮されたレスポンスを自動的にキャッシュに保存し、圧縮率とレスポンス時間の最適な組み合わせを実現します。
CDN の導入には、軽微なものから重大なものまで、さまざまな労力がかかりますが、ウェブサイトでまだ CDN を使用していない場合は、TTFB の最適化を優先する必要があります。
可能な場合はキャッシュに保存されたコンテンツを使用する
CDN を使用すると、コンテンツが適切な Cache-Control
HTTP ヘッダーで構成されている場合、訪問者に物理的に近いエッジサーバーにコンテンツをキャッシュに保存できます。これはパーソナライズされたコンテンツには適していませんが、送信元まで戻る必要がある場合、CDN の価値の多くが損なわれる可能性があります。
コンテンツを頻繁に更新するサイトでは、キャッシュに保存する時間が短くても、トラフィックの多いサイトではパフォーマンスが大幅に向上する可能性があります。その期間に最初の訪問者だけが送信元サーバーにアクセスする際に完全なレイテンシが発生し、他のすべての訪問者はエッジサーバーからキャッシュに保存されたリソースを再利用できるからです。一部の CDN では、サイトのリリース時にキャッシュの無効化を許可しているため、キャッシュ時間は長くなりますが、必要に応じて即時更新できます。
キャッシュが正しく設定されている場合でも、アナリティクスの測定に固有のクエリ文字列パラメータを使用すると、この問題を無視できます。同じコンテンツであっても、CDN から見ると異なるコンテンツのように見えるため、キャッシュに保存されたバージョンは使用されません。
古いコンテンツやアクセス頻度の低いコンテンツはキャッシュに保存されないため、一部のページの TTFB 値が他のページよりも高くなる可能性があります。キャッシュ時間の増加により、この影響を軽減できますが、キャッシュ時間の増加に伴い、古いコンテンツが配信される可能性も高くなります。
キャッシュに保存されたコンテンツの影響は、CDN を使用しているユーザーに限りません。キャッシュに保存されたコンテンツを再利用できない場合は、サーバー インフラストラクチャでコストの高いデータベース ルックアップからコンテンツを生成する必要があります。頻繁にアクセスされるデータやプリキャッシュされたページは、多くの場合パフォーマンスが向上します。
複数のページ リダイレクトを避ける
TTFB の増加につながる一般的な要因の 1 つはリダイレクトです。リダイレクトは、ドキュメントのナビゲーション リクエストで、リソースが別の場所にあることをブラウザに通知するレスポンスが受信された場合に発生します。1 つのリダイレクトによって、ナビゲーション リクエストに望ましくないレイテンシが追加される可能性がありますが、そのリダイレクトが別のリソースを参照し、別のリダイレクトが発生すると、さらに悪化する可能性があります。特に、広告やニュースレターから大量のユーザーが訪れるサイトでは、測定目的で分析サービス経由でリダイレクトされることが多いため、影響が大きくなる可能性があります。直接管理しているリダイレクトを排除すると、TTFB を改善できます。
リダイレクトには次の 2 種類があります。
- 同一オリジンのリダイレクト: リダイレクトはすべてウェブサイトで行われます。
- クロスオリジン リダイレクト: リダイレクトは、ウェブサイトに到達する前に、別のオリジン(ソーシャル メディアの URL 短縮サービスなど)で最初に発生します。
同一オリジンのリダイレクトは直接制御できるため、このリダイレクトの排除に重点を置く必要があります。そのためには、ウェブサイト上のリンクをチェックして、302
または 301
レスポンス コードが返されるリンクがないか確認する必要があります。多くの場合、これは https://
スキームが含まれていないため(ブラウザがデフォルトで http://
になり、リダイレクトされるため)、または URL に末尾のスラッシュが適切に含まれていないか除外されていることが原因です。
クロスオリジン リダイレクトは、多くの場合管理できないため、より複雑になりますが、可能であれば複数のリダイレクトを回避してください。たとえば、リンクを共有するときに複数のリンク短縮ツールを使用するなどです。広告主またはニュースレターに指定した URL が正しい最終ページ URL であることを確認してください。そうすることで、これらのサービスで使用されているリダイレクトに別のリダイレクトを追加する必要がなくなります。
リダイレクト時間のもう 1 つの重要な原因は、HTTP から HTTPS へのリダイレクトです。この問題を回避する 1 つの方法は、Strict-Transport-Security
ヘッダー(HSTS)を使用することです。これにより、オリジンへの初回アクセス時に HTTPS が適用され、以降のアクセスでは HTTPS スキームを介してオリジンにすぐにアクセスするようブラウザに指示されます。
適切な HSTS ポリシーを設定したら、サイトを HSTS プリロード リストに追加することで、オリジンへの初回アクセスを高速化できます。
マークアップをブラウザにストリーミングする
ブラウザは、ストリーミング時にマークアップを効率的に処理するように最適化されています。つまり、マークアップはサーバーから届くたびにチャンクで処理されます。これは、大きなマークアップ ペイロードが関係する場合に重要です。レスポンス全体が届くのを待ってから解析を開始するのではなく、ブラウザがマークアップのチャンクを段階的に解析できるためです。
ブラウザはストリーミング マークアップを処理するのに優れていますが、最初のマークアップ ビットができるだけ早く送信されるように、ストリーミングを維持するためにできる限りのことをすることが重要です。バックエンドが処理を遅らせている場合は、問題です。バックエンド スタックは多数あるため、すべてのスタックと、各スタックで発生する可能性のある問題を網羅することは、このガイドの範囲を超えています。
たとえば、React や、サーバー上でマークアップをオンデマンドでレンダリングできる他のフレームワークでは、サーバーサイド レンダリングに同期アプローチが使用されています。ただし、新しいバージョンの React には、レンダリング中にマークアップをストリーミングするサーバー メソッドが実装されています。つまり、React サーバー API メソッドがレスポンスをレンダリングして送信するまで待つ必要はありません。
マークアップをブラウザに迅速にストリーミングするもう 1 つの方法は、ビルド時に HTML ファイルを生成する静的レンダリングを使用することです。ファイル全体をすぐに利用できる状態にしておけば、ウェブサーバーはファイルをすぐに送信できます。HTTP の固有の性質により、マークアップがストリーミングされます。このアプローチは、ユーザー エクスペリエンスの一部として動的レスポンスを必要とするページなど、すべてのウェブサイトのすべてのページに適しているわけではありませんが、特定のユーザーに合わせてマークアップをパーソナライズする必要がないページには有効です。
サービス ワーカーを使用する
Service Worker API は、ドキュメントとそのドキュメントが読み込むリソースの両方の TTFB に大きな影響を与える可能性があります。これは、サービス ワーカーがブラウザとサーバー間のプロキシとして機能するためです。ただし、ウェブサイトの TTFB に影響があるかどうかは、サービス ワーカーの設定方法と、その設定がアプリケーションの要件と一致しているかどうかによって異なります。
- アセットに再検証中の古いデータを使用する戦略を使用する。アセットがサービス ワーカー キャッシュにある場合(ドキュメントまたはドキュメントに必要なリソース)、古いリソースの再検証戦略では、まずキャッシュからそのリソースが提供され、次にそのアセットがバックグラウンドでダウンロードされ、今後の操作のためにキャッシュから提供されます。
- 変更頻度の低いドキュメント リソースがある場合は、Stale-while-revalidate 戦略を使用すると、ページの TTFB をほぼ瞬時にすることができます。ただし、ウェブサイトが動的に生成されたマークアップ(ユーザーの認証状況に応じて変化するマークアップなど)を送信する場合は、この方法は適していません。このような場合は、ドキュメントをできるだけ最新の状態に保つため、常にネットワークを先に参照します。
- ドキュメントで、頻繁に変更されるが、古いリソースを取得してもユーザー エクスペリエンスに大きな影響を与えないリソース(特定の画像やその他の重要でないリソースなど)を読み込む場合は、古いリソースを取得しながら再検証する戦略を使用して、これらのリソースの TTFB を大幅に短縮できます。
- クライアント レンダリング アプリケーションにはアプリシェル モデルを使用します。このモデルは、ページの「シェル」をサービス ワーカー キャッシュから即座に配信し、ページのライフサイクルの後半でページの動的コンテンツを入力してレンダリングできる SPA に最適です。
レンダリングに重要なリソースには 103 Early Hints
を使用する
アプリケーション バックエンドがどれほど最適化されていても、レスポンスの準備のためにサーバーが行う必要がある作業が大量に発生する可能性があります。これには、ナビゲーション レスポンスが可能な限り迅速に届かないようにする、費用のかかる(しかし必要な)データベース処理が含まれます。この場合、CSS や、場合によってはクライアントでマークアップをレンダリングする JavaScript など、レンダリングに不可欠な後続のリソースが遅延する可能性があります。
103 Early Hints
ヘッダーは、バックエンドがマークアップの準備に忙しい間に、サーバーがブラウザに送信できる早期レスポンス コードです。このヘッダーを使用すると、マークアップの準備中にページのダウンロードを開始する必要があるレンダリングに不可欠なリソースがあることをブラウザにヒントとして伝えることができます。対応しているブラウザでは、ドキュメントのレンダリング(CSS)とページの読み込みが高速化されます。
103 早期ヒントのデメリットの一つは、キャッシュと同様に、サイトの「実際の」TTFB を隠してしまう可能性があることです。サーバー インフラストラクチャが遅い場合(処理能力が不足している場合やコードを最適化する必要がある場合)、103 早期ヒントが使用されていると、TTFB が速く見えるため、その遅さがわかりづらい場合があります。103 早期ヒントを使用するサイトは、実際のサーバー時間(PerformanceNavigationTiming API の Server-Timing
または finalResponseHeadersStart
)の測定を検討する必要があります。
まとめ
バックエンド アプリケーション スタックの組み合わせは非常に多いため、ウェブサイトの TTFB を短縮するためにできることをすべて網羅した記事はありません。ただし、サーバーサイドで処理を少しでも速くするために、以下の方法を検討できます。
他の指標の最適化と同様に、アプローチはほぼ同じです。フィールドで TTFB を測定し、ラボツールを使用して原因をドリルダウンし、可能であれば最適化を適用します。ここに記載されているテクニックはすべて、状況に応じて有効なものではありませんが、一部は有効です。いつものように、フィールドデータを注意深く確認し、必要に応じて調整して、可能な限り高速なユーザー エクスペリエンスを実現する必要があります。
ヒーロー画像: Taylor Vick、Unsplash より