Time to First Byte (TTFB) の問題の特定と修正
RUM データ、Server-Timing ヘッダー、および体系的な TTFB サブパーツ分析を使用して、ページの Time to First Byte の問題をデバッグする方法を学びます。

Time to First Byte (TTFB) の問題の特定と修正
この記事は、Time to First Byte (TTFB) ガイドの一部です。TTFB は、ユーザーがページをリクエストしてからブラウザがレスポンスの最初のバイトを受信するまでの時間を測定する診断指標です。TTFB 自体は Core Web Vitals ではありませんが、First Contentful Paint (FCP) と Largest Contentful Paint (LCP) の両方に直接影響します。優れた TTFB は、75パーセンタイルで800ミリ秒未満です。
前回の記事では、Time to First Byte について説明しました。基礎について詳しく知りたい場合は、そこから始めるのが最適です。
この記事では、さまざまな Time to First Byte の問題の特定に焦点を当て、その修正方法を説明します。
TTFB のヒント: 初回訪問者はサイトの DNS キャッシュを持っていないため、ほとんどの場合、初回訪問者の TTFB ははるかに悪化します。TTFB をトラッキングする際は、初回訪問者とリピーターを区別することが非常に重要です。
Table of Contents!
- Time to First Byte (TTFB) の問題の特定と修正
- ステップ 1: Search Console で TTFB を確認する
- ステップ 1b: Server-Timing ヘッダーを使用してより深い洞察を得る
- ステップ 2: RUM トラッキングを設定する
- ステップ 2b: パフォーマンスのベースラインを確立する
- ステップ 3: Time to First Byte の問題を特定する
- ステップ 4: 問題を拡大して修正する
- ステップ 5: 一般的な TTFB の問題に関するクイックフィックスチェックリスト
- JavaScript で TTFB を測定する
- 参考資料: 最適化ガイド
- TTFB サブパーツ: 完全ガイド
ステップ 1: Search Console で TTFB を確認する
「回復への第一歩は、問題があることを認めることである。」したがって、Time to First Byte を修正するための行動を起こす前に、TTFB に本当に問題があるのかどうかを確認しましょう。
残念ながら、Time to First Byte は Google Search Console ではレポートされないため、サイトの CrUX データを照会するには pagespeed.web.dev に頼る必要があります。幸い、手順は簡単です。pagespeed.web.dev にアクセスし、ページの URL を入力して、「origin」ボタンがオンになっていることを確認します(ホームページのデータだけでなく、サイト全体のデータが必要なため)。次に、モバイルとデスクトップを切り替えて、両方のデバイスタイプで Time to First Byte を確認します。
以下の例では、TTFB が高いため Core Web Vitals に不合格となっているサイトを確認できます。

ステップ 1b: Server-Timing ヘッダーを使用してより深い洞察を得る
Server-Timing HTTP レスポンスヘッダーを使用すると、サーバーからバックエンドのパフォーマンス指標を直接ブラウザに伝えることができます。これにより、サーバーログにアクセスすることなく、サーバー処理のどの部分が遅いかを正確に特定できます。
一般的な Server-Timing ヘッダーは次のようになります:
Server-Timing: db;dur=53, app;dur=120, cache;desc="miss"
この例では、サーバーは 3 つのタイミング値を報告しています:
- db;dur=53: データベースクエリに 53 ミリ秒かかりました。
- app;dur=120: アプリケーションロジック (テンプレートのレンダリング、API 呼び出しなど) に 120 ミリ秒かかりました。
- cache;desc="miss": このリクエストではサーバーキャッシュは使用されませんでした (キャッシュミス)。
これらの値は、Chrome DevTools で [Network] タブを開き、ドキュメントのリクエストを選択して、[Timing] タブの [Server Timing] セクションまでスクロールすることで確認できます。また、JavaScript の PerformanceServerTiming API を通じてアクセスすることも可能です:
const [navigation] = performance.getEntriesByType('navigation');
if (navigation.serverTiming) {
navigation.serverTiming.forEach(entry => {
console.log(`${entry.name}: ${entry.duration}ms (${entry.description})`);
});
}
サーバーがまだ Server-Timing ヘッダーを送信していない場合は、追加を検討してください。ほとんどの Web フレームワークでは、これは簡単に設定できます。PHP の場合、出力前にヘッダーを追加できます:
header('Server-Timing: db;dur=' . $dbTime . ', app;dur=' . $appTime);
Node.js と Express の場合:
res.setHeader('Server-Timing', `db;dur=${dbTime}, app;dur=${appTime}`);
Server-Timing ヘッダーは、サーバー側のパフォーマンスを実際のユーザーが体験する TTFB と関連付けることができるため、Real User Monitoring (RUM) と組み合わせると特に便利です。完全なレスポンスの準備ができる前にリソースヒントを送信することで、ユーザーが体感する TTFB をさらに短縮できる 103 Early Hints について詳しく学びましょう。
ステップ 2: RUM トラッキングを設定する
Time to First Byte は扱いが難しい指標です。現実の環境では他の要因が TTFB の変動に寄与するため、単に合成テストに依存して TTFB を測定することはできません。上記のすべての質問に対する答えを得るには、実際のデータを測定し、Time to First Byte で発生する可能性のあるあらゆる問題をログに記録する必要があります。これは Real User Monitoring (RUM) と呼ばれ、RUM トラッキングを有効にするにはいくつかの方法があります。私たちはまさにこれらのユースケースのために CoreDash を開発しました。CoreDash は、低コストで高速かつ効果的に機能する RUM ツールです。もちろん、世の中には多くの RUM ソリューションがあり、それらも役立ちますが(より高価にはなります)。

TTFB の考え方: Web サーバーをレストランの厨房、Web ページをリクエストするユーザーを注文をするお腹を空かせた顧客だと想像してください。Time to First Byte (TTFB) とは、顧客が注文を行ってから厨房が料理の準備を始めるまでの時間です。
したがって、TTFB は食事全体がどれだけ早く調理され (First Contentful Paint) 提供されたか (Largest Contentful Paint) ではなく、最初の要求に対して厨房がどれだけ迅速に応答したかを示します。
RUM トラッキングは、食事の体験を理解するために顧客を調査することに例えられます。厨房から遠い席に座っている顧客はウェイターの注意を引きにくく提供が遅れることや、リピーターは優遇される一方で新規訪問者は席に着くまでに長く待たなければならないことなどが分かるかもしれません。
ステップ 2b: パフォーマンスのベースラインを確立する
変更を加える前に、TTFB のベースラインを確立してください。後で最適化の効果を測定するのに役立つため、以下の次元全体で 75 パーセンタイルの TTFB を記録します:
- 全体的な TTFB (モバイルとデスクトップを別々に): 各デバイスタイプの 75 パーセンタイルを記録します。
- トラフィックの多い上位 10 ページ: トラフィックが最も多いページの TTFB を個別に記録します。
- 新規訪問者とリピーター: DNS と接続のオーバーヘッドのため、通常、初回訪問者の TTFB は高くなります。
- トラフィックの多い上位 5 カ国: サーバーまでの地理的距離は TTFB に大きな影響を与えます。
- TTFB サブパーツの内訳: 各サブパーツ (待機、キャッシュ、DNS、接続、リクエスト) の 75 パーセンタイルを記録します。
これらの数値をスプレッドシートに記録します。各最適化を実装した後、十分な RUM データを収集するために少なくとも 7 日間待ってから結果を比較してください。TTFB のサブパーツに 1 つずつ取り組み、測定してから次へ進むのが良いアプローチです。
ステップ 3: Time to First Byte の問題を特定する
Google の Chrome User Experience Report (CrUX) は価値のあるフィールドデータを提供しますが、高い TTFB の原因に関する具体的な詳細は提供しません。TTFB を効果的に改善するには、より詳細なレベルで正確に何が起こっているかを知る必要があります。この時点では、全体的に失敗している TTFB と、特定の条件下で失敗している TTFB を区別することが合理的です (現実には常に混ざり合っていますが)。
3.1 TTFB が全体的に失敗している
- 全体的に悪い「リクエスト時間」を確認する: リクエスト時間が悪いということは、サーバーがページを生成するのにかかる時間に「問題」があることを意味します。これが TTFB スコアが悪化する最も一般的な原因です。
- 他の悪い TTFB サブパーツを確認する: TTFB は単一の指標ではなく、それぞれ独自の最適化の可能性を持つ複数の部分に分割できます。待機時間 (waiting duration)、キャッシュ時間 (cache duration)、DNS ルックアップ時間 (DNS lookup duration)、または 接続時間 (connection duration) が遅い場合は、おそらくサーバー設定を調整するか、より高品質なホスティングを探し始める必要があります。

3.2 特定の条件下で TTFB が失敗している
- 国別のセグメンテーション: TTFB が高い地域の分布を理解することは、特に世界中のユーザーを持つ Web サイトにとって重要です。1 つの国にある 1 つのサーバーからのみページを提供している場合(CDN エッジキャッシュなし)、ユーザーの場所と Web サイトをホストしているサーバー間の物理的な距離がさまざまな遅延を引き起こし、TTFB に影響を与えます。Cloudflare の構成やその他の CDN を検討して、コンテンツを世界中のユーザーに近づけましょう。

- キャッシュのセグメンテーション: キャッシュを使用すると、サーバー側での HTML 生成をスキップして TTFB を短縮できます。残念ながら、多くの理由によりキャッシュが無効化されたりバイパスされたりすることがよくあります。たとえば、ログインしているユーザー、ショッピングカートのページ、クエリ文字列を持つページ(Google 広告など)、検索結果ページ、チェックアウトページなどではキャッシュが無効になることがあります。Web サイトで(エッジ)キャッシュを使用している場合は、RUM トラッキングを使用してキャッシュヒット率を確認してください。

- ページ(クラスター)のセグメンテーション: ページ間またはページタイプ間の Time to First Byte パフォーマンスの違い(または違いの欠如)も判断する必要があります。どのページが TTFB 指標に失敗しているかを知ることは、Time to First Byte を改善する方法についての貴重な洞察を与えてくれます。

- リダイレクトのセグメンテーション: リダイレクト時間は TTFB に直接追加されます。各リダイレクトにより、Web サーバーがページの読み込みを開始できるまでに追加の時間がかかります。不要なリダイレクトを測定して排除することで、TTFB の改善に役立ちます。リダイレクトの最適化の詳細については、TTFB の待機時間のサブパーツのガイドを参照してください。

- その他のセグメンテーション: 上記の変数によるセグメンテーションは一般的な原因をカバーしていますが、各サイトはユニークであり、独自の課題を抱えています。幸い、RUM トラッキングは、デバイスの RAM、ネットワーク速度、デバイスタイプ、オペレーティングシステム、カスタム変数など、さらに多くの変数によるセグメンテーションを可能にするように設計されています。
ステップ 4: 問題を拡大して修正する

Time to First Byte (TTFB) のサブパーツは次のとおりです:
- Waiting + Redirect (待機 + リダイレクトまたは待機時間)
- Worker + Cache (ワーカー + キャッシュまたはキャッシュ時間)
- DNS (または DNS 時間)
- Connection (接続または接続時間)
- Request (リクエストまたはリクエスト時間)
ステップ 5: 一般的な TTFB の問題に関するクイックフィックスチェックリスト
TTFB に最も寄与しているサブパーツに基づいて、最も一般的な修正のクイックリファレンスを以下に示します:
| TTFB サブパーツ | 最も一般的な原因 | クイックフィックス |
|---|---|---|
| 待機時間 | 不要なリダイレクト | リダイレクトチェーンを監査して排除する。HSTS を実装する |
| キャッシュ時間 | Service Worker の起動が遅い | Service Worker のコードを簡素化する。効率的なキャッシュ戦略を使用する |
| DNS 時間 | 遅い DNS プロバイダー | Cloudflare などのプレミアム DNS プロバイダーに切り替える。TTL 設定を調整する |
| 接続時間 | 古い TLS バージョン | TLS 1.3 と HTTP/3 を有効にする。近接性を高めるために CDN を使用する |
| リクエスト時間 | サーバーの処理が遅い | サーバー側のキャッシュを実装する。データベースのクエリを最適化する。103 Early Hints を使用する |
JavaScript で TTFB を測定する
Navigation Timing API を使用すると、ブラウザ上で完全な TTFB とそのサブパーツを直接測定できます。以下のスニペットは TTFB を計算し、各サブパーツをログに記録します:
new PerformanceObserver((entryList) => {
const [nav] = entryList.getEntriesByType('navigation');
const activationStart = nav.activationStart || 0;
const ttfb = nav.responseStart - activationStart;
const waitingDuration = (nav.workerStart || nav.fetchStart) - activationStart;
const cacheDuration = nav.domainLookupStart - (nav.workerStart || nav.fetchStart);
const dnsDuration = nav.domainLookupEnd - nav.domainLookupStart;
const connectionDuration = nav.connectEnd - nav.connectStart;
const requestDuration = nav.responseStart - nav.requestStart;
console.log('TTFB:', ttfb.toFixed(0), 'ms');
console.log(' Waiting:', waitingDuration.toFixed(0), 'ms');
console.log(' Cache:', cacheDuration.toFixed(0), 'ms');
console.log(' DNS:', dnsDuration.toFixed(0), 'ms');
console.log(' Connection:', connectionDuration.toFixed(0), 'ms');
console.log(' Request:', requestDuration.toFixed(0), 'ms');
}).observe({
type: 'navigation',
buffered: true
});
このコードは、CoreDash などのツールが TTFB アトリビューションパネルに表示するのと同じ内訳を提供します。このスニペットをブラウザのコンソールで実行すると、単一のページ読み込みに対する数値を即座に読み取ることができます。一方、RUM ツールは何千人もの実際のユーザーからこのデータを収集して、信頼性の高い 75 パーセンタイルの値を生成します。
参考資料: 最適化ガイド
関連ガイド:
- 103 Early Hints: 完全なレスポンスの準備ができる前にリソースヒントを送信し、サーバーが処理を続けている間にブラウザが重要なリソースの読み込みを開始できるようにします。
- パフォーマンスのための Cloudflare の構成: Cloudflare の CDN、キャッシュ、エッジ機能を設定して、グローバルなユーザー向けの TTFB を短縮します。
TTFB サブパーツ: 完全ガイド
Time to First Byte の各サブパーツには独自の最適化戦略があります。RUM データでボトルネックとして特定されたサブパーツから始めましょう:

