ソフト ナビゲーションの測定

公開日: 2023 年 2 月 1 日、最終更新日: 2026 年 6 月 24 日

Core Web Vitals の取り組みは、開始以来、ウェブサイトの作成方法や読み込み方法の技術的な詳細ではなく、ウェブサイトの実際のユーザー エクスペリエンスを測定することを目的としてきました。ウェブに関する主な指標の 3 つの指標は、ユーザー中心の指標として作成されました。これは、DOMContentLoadedload などの既存の技術指標の進化版です。これらの技術指標は、ユーザーがページのパフォーマンスをどのように認識するかとは無関係なタイミングを測定することがよくありました。そのため、サイトのパフォーマンスが良好であれば、サイトの構築に使用されたテクノロジーがスコアに影響することはありません。

実際には理想どおりにはいかないことが多く、一般的なシングルページ アプリケーション アーキテクチャは、Core Web Vitals の指標で完全にサポートされたことはありません。ユーザーがサイト内を移動するたびに個別のウェブページを読み込むのではなく、これらのウェブ アプリケーションでは「ソフト ナビゲーション」と呼ばれる手法が使用されます。この手法では、JavaScript によってページ コンテンツが変更されます。このようなアプリケーションでは、URL を変更し、ブラウザの履歴に前の URL をプッシュすることで、従来のウェブページのアーキテクチャの錯覚を維持し、ユーザーが期待する動作を [戻る] ボタンと [進む] ボタンで実現しています。

多くの JavaScript フレームワークがこのモデルを使用していますが、それぞれ異なる方法で使用しています。これはブラウザが従来「ページ」として認識していたものとは異なるため、測定は常に困難でした。現在のページでのインタラクションと、新しいページでのインタラクションの境界線はどこにあるのでしょうか?

Chrome チームは、この課題をしばらく検討しており、従来のマルチページ アーキテクチャ(MPA)で実装されたウェブサイトが測定されるのと同様の方法で、「ソフト ナビゲーション」の定義と、この定義に沿って Core Web Vitals を測定する方法を標準化しようとしています。

デベロッパーからのフィードバックに基づいてプロポーザルにいくつかの改善を加え、Chrome 151 からこの問題の解決に役立つ 2 つの新しいパフォーマンス API をリリースすることを目指しています。

ソフト ナビゲーションとは

ソフト ナビゲーションの定義は次のとおりです。

  • ナビゲーションはユーザー アクションによって開始されます。
  • ナビゲーションの結果、ユーザーに表示される URL が変更されます。
  • インタラクションの結果としてペイントが可視化されます。

一部のサイトでは、この定義により、誤検出(ユーザーが「ナビゲーション」が発生したとは考えない場合)や誤検出(ユーザーが「ナビゲーション」が発生したと考える場合でも、この条件を満たしていない場合)が発生する可能性があります。フィードバックは、ソフト ナビゲーションの仕様リポジトリでお待ちしています。

ソフト ナビゲーションの DevTools サポート

トレースビューの DevTools のパフォーマンス パネルに、ソフト ナビゲーションのサポートを追加しました。

パフォーマンス パネルのソフト ナビゲーション マーカー。youtube.com のトレースが表示されています。

ソフト ナビゲーションと LCP のマーカーが表示されます。どちらも * でマークされており、通常のハード ナビゲーション エントリと区別できます。これはデフォルトで有効になっており、次に説明するパフォーマンス API の変更とは異なります。これは、サイトでソフト ナビゲーションの検出が正しく機能するかどうかをすばやくテストする方法です。

現時点では、トレースビューにソフト ナビゲーションと LCP のタイムスタンプのみが表示されます。その他の指標(LCP など)と [ライブ指標] ビューのサポートは、後日追加される予定です。

Chrome はウェブ デベロッパー向けにソフト ナビゲーションをどのように実装していますか?

ソフト ナビゲーション機能が有効になると(詳しくは次のセクションをご覧ください)、Chrome は一部のパフォーマンス指標のレポート方法を変更します。

  • ソフト ナビゲーションが検出されるたびに、soft-navigation PerformanceTiming イベントが発行されます。
  • この soft-navigation エントリには、navigationIdname 属性の新しい URL、開始インタラクションの interactionId が含まれます。
  • コンテンツフル ペイントを引き起こすインタラクションの後、1 つ以上の interaction-contentful-paint エントリが発行されます。これには、ソフト ナビゲーションの Largest Contentful Paint(LCP)を測定するために使用できる largestContentfulPaint エントリが含まれます。
  • navigationId 属性は、各パフォーマンス タイミング(first-paintfirst-contentful-paintlargest-contentful-paintinteraction-contentful-paintfirst-input-delayeventlayout-shift)に追加されます。これは、イベントが発行されたナビゲーション エントリに対応します。これらのエントリがソフト ナビゲーションにまたがる場合、エントリが発行されたタイミングに応じて、前の navigationId または次の navigationId が含まれることがあります。詳しくは、適切な URL に対して指標をレポートするをご覧ください。
  • soft-navigation には、そのナビゲーションの最大の interaction-contentful-paint エントリを取得する getLargestInteractionContentfulPaint() 関数が含まれます。これはそのナビゲーションの最初の LCP として使用され、そのインタラクションの interaction-contentful-paint エントリがさらに観測されると、その LCP が更新されます。これは、以前のオリジン トライアルで利用可能だった largestInteractionContentfulPaint 属性に代わるものです。
  • URL の更新がペイント後まで行われない場合、ソフト ナビゲーションの前に interaction-contentful-paint エントリが発生する可能性があります。このような場合、getLargestInteractionContentfulPaint() 関数を使用すると、ソフト ナビゲーションの完了後に古いエントリをバッファリングして振り返る必要がなくなります。getLargestInteractionContentfulPaint() から返されるエントリは、出力された時点での最大の interaction-contentful-paint エントリの正確なコピーであることに注意してください。そのため、そのエントリはペイントが発生した時点の以前の navigationId を使用している可能性がありますが、これらのペイントは新しい navigationId に対して測定する必要があります。
  • soft-navigation エントリには、そのナビゲーションの FCP として paintTimepresentationTime も含まれます。
  • interaction-contentful-paint エントリは、その後の操作の後にも出力されますが、URL の LCP は、ソフト ナビゲーション interactionId に一致する interaction-contentful-paint エントリに限定して、それらを除外する必要があります。また、その中の largestContentfulPaint プロパティに限定する必要があります。

これらの変更により、Core Web Vitals と関連する診断指標の一部をページ ナビゲーションごとに測定できるようになりますが、考慮すべきニュアンスがいくつかあります。

Chrome でソフト ナビゲーションを有効にするとどうなりますか?

この機能を有効にした後、サイト所有者が考慮する必要がある変更は次のとおりです。

  • soft-navigation エントリをモニタリングすることで、パフォーマンス エントリを各「ナビゲーション」に「スライス」できます。
  • CLS と INP の指標は、ページ ライフサイクル全体にわたって測定されるのではなく、すでに任意でスライスできますが、ソフト ナビゲーション機能を使用すると、使用されている基盤となるテクノロジーに関係なく、このタイミングを標準化された指標で把握できます。
  • largest-contentful-paint エントリはインタラクションで確定されるため(ソフト ナビゲーションを開始するために必要)、最初の「ハード」ナビゲーションの LCP を測定するためにのみ使用できます。つまり、ソフト ナビゲーションが測定されてもこの値は変更されないため、最初のハード ナビゲーションのページ読み込みの LCP をこれまでどおり測定できます。
  • インタラクションから出力される新しい interaction-contentful-paint エントリを使用すると、その中の largestContentfulPaint プロパティを確認することで、ソフト ナビゲーションの LCP を測定できます。ただし、このエントリの使用方法については考慮すべき点があります。この記事では、それについて説明します。
  • すべてのユーザーがこのソフト ナビゲーション機能をサポートしているわけではありません。特に、古い Chrome のバージョンや他のブラウザを使用しているユーザーはサポートしていません。一部のユーザーは、Core Web Vitals の指標を報告していても、ソフト ナビゲーションに基づく指標を報告しない場合があります。

RUM プロバイダに、ソフト ナビゲーションによる Core Web Vitals の測定をサポートしているかどうかを確認してください。多くの企業がこの新しい基準のテストを計画しており、以前の考慮事項を考慮する予定です。それまでの間、一部のプロバイダは独自のヒューリスティックに基づいて、パフォーマンス指標の測定を限定的に許可しています。

ソフト ナビゲーションの指標を測定する方法については、ソフト ナビゲーションごとの Core Web Vitals の測定セクションをご覧ください。

Chrome でソフト ナビゲーションを有効にするにはどうすればよいですか?

ソフト ナビゲーション機能は、Chrome 151 でデフォルトで有効になる予定ですが、この機能を明示的に有効にすることで、それ以前にテストできます。

デベロッパーは、chrome://flags/#soft-navigation-heuristics でフラグをオンにすることで、この機能を有効にできます。または、Chrome の起動時に --enable-features=SoftNavigationHeuristics コマンドライン引数を使用して有効にすることもできます。chrome://flags/#enable-experimental-web-platform-features フラグを有効にすると、ソフト ナビゲーションも有効になります。

一部のウェブサイト所有者は、オリジン トライアル プロセスを通じて、リリース前にサイトでこの機能を有効にしています。API の形状は機能の開発を通じて変更されており、最終的にリリースされた機能は、ソフト ナビゲーションの変更履歴で説明されているように、以前のオリジン トライアルとは異なります。

ソフト ナビゲーション API のサポートを検出する機能

次のコードを使用して、API がサポートされているかどうかをテストできます。

if (PerformanceObserver.supportedEntryTypes.includes('soft-navigation')) {
  // Monitor Soft Navigations
}

supportedEntryTypes は初回使用時にフリーズされるため、ページに挿入されたオリジン トライアル トークンによってソフト ナビゲーションのサポートが動的に追加された場合、この機能が有効になる前の元の値が返されることがあります。

この場合、ソフト ナビゲーションがデフォルトでサポートされておらず、この移行状態にある間は、次の代替手段を使用できます。

if ('SoftNavigationEntry' in window) {
  // Monitor Soft Navigations
}

ソフト ナビゲーションを測定するにはどうすればよいですか?

ソフト ナビゲーションの検出が有効になると、他の指標と同様に PerformanceObserver API を使用して指標がレポートされるようになります。ただし、これらの指標については、考慮すべき点がいくつかあります。

ソフト ナビゲーションを報告する

PerformanceObserver を使用して、ソフト ナビゲーションを観察できます。次のコード スニペットは、buffered オプションを使用して、このページの以前のソフト ナビゲーションを含むソフト ナビゲーション エントリをコンソールに記録する例です。

const observer = new PerformanceObserver(console.log);
observer.observe({ type: "soft-navigation", buffered: true });

これは、前のナビゲーションのフルライフ ページ指標を確定するために使用できます。

適切な URL に対して指標をレポートする

ソフト ナビゲーションが検出されたら、前のページのウェブに関する主な指標を確定し、前の URL についてレポートし、新しい URL について新しいモニタリングを開始する必要があります。

適切な soft-navigation エントリの name 属性には、指標をレポートする新しい URL が含まれます。navigationId は、このナビゲーションの一意の参照になります(同じ URL がシングルページ アプリケーションのライフサイクル中に複数回アクセスされる可能性があるため)。

これは各 soft-navigation エントリとして設定され、次の soft-navigation エントリが受信されるまで指標のレポートに使用されます。

interaction-contentful-paint の正しい URL を報告する

すべての interaction-contentful-paint エントリを navigationId を使用してマッピングし、その URL の LCP として報告する必要はないため、interaction-contentful-paint エントリから LCP を計算するには、追加の考慮事項が必要です。

  • 1 つ目の問題は、URL の更新前にペイントが発生した場合、ソフト ナビゲーションが発生する前に interaction-contentful-paint エントリが発行される可能性があることです。この場合、navigationId は古い URL のものになります。URL が先に更新された場合、ペイントはソフト ナビゲーションを完了します。この場合、soft-navigation エントリが最初に発行され、interaction-contentful-paint には新しい URL が含まれます。
  • 2 つ目の問題は、このパフォーマンス指標の範囲がソフト ナビゲーションの LCP を超えて拡張されているため、新しいインタラクションに対して interaction-contentful-paint エントリが引き続き出力されることです。LCP では、ソフト ナビゲーションの読み込みのペイントのみを考慮し、その後のインタラクションのペイントは考慮しません。

したがって、正しい URL を取得するには、navigationId ではなく interactionId を使用して interaction-contentful-paint エントリを soft-navigation-entries にマッピングする必要があります。これにより、古い navigationId を含むエントリが処理され、LCP の対象とすべきでない interaction-contentful-paint エントリがフィルタで除外されます。

また、soft-navigation entries が出力される前に発生する interaction-contentful-paint エントリをより簡単に処理するために、soft-navigation エントリの getLargestInteractionContentfulPaint() 関数も処理することを検討してください。

ソフト ナビゲーションの startTime を取得する

ソフト ナビゲーションを含むすべてのパフォーマンス タイミングと、ウェブに関する主な指標の計算に使用されるエントリは、最初の「ハード」ページ ナビゲーションからの時間としてレポートされます。そのため、ソフト ナビゲーションの開始時刻をソフト ナビゲーションの読み込み指標の時刻(LCP など)から差し引いて、このソフト ナビゲーションの時刻を基準にレポートする必要があります。

ナビゲーションの開始時刻も同様に、適切な soft-navigation エントリにマッピングしてその startTime を使用することで取得できます。

startTime は、ソフト ナビゲーションを開始した最初の操作(ボタンのクリックなど)の時刻です。これは「ハード ナビゲーション」とは多少異なります。ハード ナビゲーションでは、「開始時間」は新しいページがブラウザに「コミット」され、一部のイベント ハンドラ コードが実行されたときです。ソフト ナビゲーションの開始時間には、インタラクションの開始時間から測定するため、イベント ハンドラ コードも含まれます。

ソフト ナビゲーションごとに Core Web Vitals を測定する

Core Web Vitals を測定するには、soft-navigation エントリをリッスンし、これらのエントリを受信したら指標をリセットします。FCP は presentationTime に基づいて出力でき、LCP は getLargestInteractionContentfulPaint() エントリに初期化できます。INP と CLS は、ページ読み込みの場合と同様に 0 に初期化する必要があります。

その後、LCP、INP、CLS を通常どおり測定してモニタリングできます(LCP に interaction-contentful-paint を使用して interactionId の一致を取得する場合を除く)。interactionId を使用して、前述のように URL のエントリに名前を付けることができます。

タイミングは、元の「ハード」ナビゲーションの開始時刻を基準として返されます。たとえば、ソフト ナビゲーションの LCP を計算するには、interaction-contentful-paint のタイミングを取得し、前述のように適切なソフト ナビゲーションの開始時間を差し引いて、ソフト ナビゲーションを基準としたタイミングを取得する必要があります。

一部の指標は、ページのライフサイクル全体で測定されてきました。たとえば、LCP はインタラクションが発生するまで変化する可能性があります。CLS と INP は、操作の有無にかかわらず、ページから移動するまで更新できます。そのため、新しいソフト ナビゲーションが発生するたびに、以前のナビゲーションの指標を確定する必要があります。つまり、ソフト ナビゲーションで Core Web Vitals を測定する場合、初期の「ハード」Navigation 指標が通常よりも早く確定する可能性があります。

同様に、これらの長期的な指標の新しいソフト ナビゲーションの指標の測定を開始するときに、指標を「リセット」または「再初期化」して、以前の「ページ」に設定された値を記憶しない新しい指標として扱う必要があります。つまり、「最大」のペイント、Interaction to Next Paint、レイアウト シフトの理解がリセットされ、最初から測定できるようになります。

ナビゲーション間で同じコンテンツはどのように扱うべきですか?

ソフト ナビゲーションの LCP(interaction-contentful-paint から計算)では、新しいペイントのみが測定され、ナビゲーションを引き起こしたインタラクションに関連付けられたペイントのみが測定されます。これにより、ソフト ナビゲーションのコールド スタートの読み込みからソフトロードまで、LCP が異なる可能性があります。

たとえば、LCP 要素である大きなバナー画像を含むページで、その下のテキストがソフト ナビゲーションごとに変化する場合を考えてみましょう。ページの初回読み込み時に、バナー画像が LCP 要素としてフラグ設定され、それに基づいて LCP のタイミングが決定されます。以降のソフト ナビゲーションでは、その下に表示されるテキストがソフト ナビゲーション後に描画される最大の要素となり、新しい LCP 要素となります。ただし、ソフト ナビゲーション URL へのディープリンクでページが読み込まれた場合、バナー画像は新しいペイントになるため、LCP 要素と見なされる可能性があります。

同様に、アニメーションは、ソフト ナビゲーションとは無関係に、ページの一部を継続的に更新している可能性があります。その背景アニメーションによる新しいペイントは、新しいソフト ナビゲーションの LCP の対象にはなりません。ただし、この URL からページが再読み込みされた場合は、LCP の対象となる可能性があります。

これらの例に示すように、ソフト ナビゲーションの LCP 要素は、ページの読み込み方法によって異なるレポートが生成されることがあります。これは、ページの下部にあるアンカーリンクを使用してページを読み込むと、ハード ナビゲーションの LCP 要素が異なる結果になる場合があるのと同様です。

TTFB の測定方法

従来のページ読み込みの Time to First Byte(TTFB)は、元のリクエストの最初のバイトが返されるまでの時間を表します。

ソフト ナビゲーションの場合、これはより難しい問題です。新しいページに対する最初のリクエストを測定する必要がありますか?すべてのコンテンツがアプリにすでに存在し、追加のリクエストがない場合はどうなりますか?プリフェッチで事前にリクエストが行われた場合はどうなりますか?ユーザーの視点から見て、ソフト ナビゲーションとは関係のないリクエスト(アナリティクス リクエストなど)の場合はどうなりますか?

より簡単な方法は、ソフト ナビゲーションの TTFB を 0 としてレポートすることです。これは、バックフォワード キャッシュの復元でおすすめしている方法と同様です。これは、web-vitals ライブラリがソフト ナビゲーションに使用しているメソッドであり、現時点でこの指標に推奨されるメソッドです。

両方の方法で Core Web Vitals を測定する必要がありますか?

これらの新しい API は Chromium ベースのブラウザでのみ利用できますが、サイトではソフト ナビゲーションでスライスし、ハード ナビゲーションでスライスし続けることで、両方を測定したい場合があります。これにより、ブラウザ間での比較や過去の傾向の比較が可能になります。

LCP の場合、現在の方法では largest-contentful-paint エントリのみを考慮し、新しい方法では largest-contentful-paint エントリと interaction-contentful-paint エントリの両方を考慮します。

CLS と INP の場合、これは、現在の方法と同様にページ ライフサイクル全体で測定し、ソフト ナビゲーションでタイムラインを個別にスライスして、新しい CLS と INP の値を個別に測定することを意味します。

指標はビーコンで送信され、分析のために 2 回保存される必要があります。

web-vitals ライブラリを使用してソフト ナビゲーションの Core Web Vitals を測定する

すべてのニュアンスを考慮する最も簡単な方法は、別の soft-navs branchソフト ナビゲーションの試験運用サポートを備えた web-vitals JavaScript ライブラリを使用することです(npmunpkg でも利用できます)。これは次のように測定できます(doTraditionalProcessingdoSoftNavProcessing は適宜置き換えてください)。

import {
  onTTFB,
  onFCP,
  onLCP,
  onCLS,
  onINP,
} from 'https://unpkg.com/web-vitals@soft-navs/dist/web-vitals.js?module';

function doTraditionalProcessing(callback) {
  ...
}

function doSoftNavProcessing(callback) {
  ...
}

onTTFB(doTraditionalProcessing);
onFCP(doTraditionalProcessing);
onLCP(doTraditionalProcessing);
onCLS(doTraditionalProcessing);
onINP(doTraditionalProcessing);

onTTFB(doSoftNavProcessing, {reportSoftNavs: true});
onFCP(doSoftNavProcessing, {reportSoftNavs: true});
onLCP(doSoftNavProcessing, {reportSoftNavs: true});
onCLS(doSoftNavProcessing, {reportSoftNavs: true});
onINP(doSoftNavProcessing, {reportSoftNavs: true});

web-vitals ライブラリは、コールバックに提供されるエントリに navigationIdnavigationURL の両方が含まれているため、前述のとおり、指標が正しい URL に対して報告されることも保証します。

web-vitals ライブラリは、ソフト ナビゲーションについて次の指標をレポートします。

指標 詳細
TTFB 0 として報告されます。
FCP ソフト ナビゲーションをトリガーしたインタラクションから、ソフト ナビゲーションの開始時間までの First Contentful Paint の時間。前のナビゲーションから存在するペイントや、インタラクションに関連付けられていないペイントは考慮されません。
LCP ソフト ナビゲーションをトリガーしたインタラクションから、ソフト ナビゲーションの開始時刻を基準とした Largest Contentful Paint の時刻。前のナビゲーションから存在する既存のペイントは、インタラクションに関連付けられていないため、考慮されません。通常どおり、ページ(またはソフト ナビゲーション)から移動するまで更新を続けることができます。LCP を確定できるのは、そのときだけです。
CLS ナビゲーション時間間のシフトの最大ウィンドウ。通常どおり、ページ(またはソフト ナビゲーション)から移動するまで更新を続けることができます。CLS はその時点で確定します。
INP ナビゲーション間の INP。通常どおり、ページ(またはソフト ナビゲーション)から移動するまで更新を続けることができます。INP が確定するのは、そのときだけです。インタラクションがない場合、値 0 は報告されません。

これらの変更は Core Web Vitals の測定の一部になりますか?

最終的な目標は、実際のユーザー エクスペリエンスとしてのパフォーマンスをより適切に測定する手段を提供することです。API のリリース後、すべてのツールで公開されるウェブに関する主な指標の測定に、これらの指標を含めることを目指しています。

API に関するウェブ デベロッパーの皆様からのフィードバックや、API がユーザー エクスペリエンスをより正確に反映しているかどうかについてのご意見をお待ちしております。このフィードバックは、ソフト ナビゲーションの GitHub リポジトリに投稿するのが最適です。ただし、Chrome の実装に関する個々のバグについては、Chrome の問題トラッカーで報告する必要があります。

CrUX でソフト ナビゲーションはどのように報告されますか?

この機能がリリースされたときに、CrUX でソフト ナビゲーションがどのように報告されるかについても、まだ決定されていません。CrUX の変更については、詳細がわかり次第、こちらでお知らせします。

フィードバック

この API に関するフィードバックは、以下の場所で積極的に募集しています。

どちらにフィードバックを送信すればよいか迷った場合は、あまり心配しないでください。どちらに送信していただいても、Google は両方の場所で問題をトリアージし、正しい場所にリダイレクトします。

変更履歴

この API は開発中に、安定版 API よりも多くの変更が加えられました。詳しくは、ソフト ナビゲーションの変更ログをご覧ください。

まとめ

ソフト ナビゲーション機能は、Core Web Vitals イニシアチブが進化して、指標に欠けている最新のウェブの一般的なパターンを測定する可能性を示すエキサイティングなアプローチです。Google は、ウェブ コミュニティ全体から多くのフィードバックを集めてきました。この開発に関心をお持ちの方は、この機会に API の形成にご協力いただき、この API で測定したい内容を確実に反映させることを強くおすすめします。

謝辞

サムネイル画像: Jordan MadridUnsplash

この取り組みは、Yoav Weiss が Google に在籍していたときに開始した取り組みの継続です。この API の開発に尽力してくれた Yoav に感謝します。