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

公開日: 2023 年 2 月 1 日、最終更新日: 2026 年 9 月 20 日

Browser Support

  • Chrome: 151.
  • Edge: 151.
  • Firefox: not supported.
  • Safari: not supported.

Source

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

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

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

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

デベロッパーからのフィードバックに基づいて提案にいくつかの改善を加え、Chrome 151 からこの問題の解決に役立つ 2 つの新しいパフォーマンス API をリリースしました。また、ソフト ナビゲーションの指標を、Chrome ユーザー エクスペリエンス レポート(CrUX)で試験運用版の指標として利用できるようにしました。

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

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

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

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

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

DevTools のパフォーマンス パネルのリアルタイム指標ビューと、分析情報とマーカーをサポートするトレースビューに、ソフト ナビゲーションのサポートが追加されました。

DevTools でソフト ナビゲーションをサポート。

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

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

  • ソフト ナビゲーションが検出されるたびに、soft-navigation PerformanceTiming イベントが発行されます。
  • この soft-navigation エントリには、navigationId、name 属性の新しい URL、開始インタラクションの interactionId が含まれます。
  • コンテンツを含む描画を引き起こすインタラクションの後に、1 つ以上の interaction-contentful-paint エントリが出力されます。これには、ソフト ナビゲーションの Largest Contentful Paint(LCP)の測定に使用できる largestContentfulPaint エントリが含まれます。
  • navigationId 属性は、各パフォーマンス タイミング(first-paint、first-contentful-paint、largest-contentful-paint、interaction-contentful-paint、first-input-delay、event、layout-shift)に追加されます。これは、イベントが発行されたナビゲーション エントリに対応します。これらのエントリがソフト ナビゲーションにまたがる場合、エントリがいつ出力されたかに応じて、前または次の navigationId が含まれることがあります。詳しくは、適切な URL に対して指標を報告するをご覧ください。
  • soft-navigation には、そのナビゲーションの最大の interaction-contentful-paint エントリを取得する getLargestInteractionContentfulPaint() 関数が含まれます。これをそのナビゲーションの初期 LCP として使用し、そのインタラクションの interaction-contentful-paint エントリがさらに観測されると、その LCP を更新できます。これは、以前のオリジン トライアルで使用可能だった largestInteractionContentfulPaint 属性に代わるものです。
  • interaction-contentful-paint エントリの一部は、ソフト ナビゲーションが行われる前に発生した可能性があります(URL の更新がそれらのペイントの後まで発生しない場合)。このような場合、getLargestInteractionContentfulPaint() 関数を使用すると、ソフト ナビゲーションが完了した後に古いエントリをバッファリングして確認する必要がなくなります。getLargestInteractionContentfulPaint() によって返されるエントリは、出力された時点での最大の interaction-contentful-paint エントリの正確なコピーです。そのため、そのエントリは、ペイントが発生した時点の以前の navigationId を使用している可能性がありますが、これらのペイントは新しい navigationId に対して測定する必要があります。
  • soft-navigation エントリには、そのナビゲーションの FCP として paintTime と presentationTime も含まれます。
  • 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 を測定できます。ただし、この記事では、このエントリの使用方法に関する考慮事項について説明します。
  • すべてのユーザーがこのソフト ナビゲーション機能を利用できるわけではありません。特に、他のブラウザや 151 より前のバージョンの Chrome を使用しているユーザーは利用できません。一部のユーザーは、Core Web Vitals 指標を報告しても、ソフト ナビゲーション ベースの指標を報告しない場合があります。

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

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

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

ソフト ナビゲーション機能は、Chrome 151 からデフォルトで有効になっています。

Soft Navigations API のサポートを検出する機能

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

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

または:

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 に対して指標をレポートする

ソフト ナビゲーションが検出されると、前のページの Core Web Vitals が確定され、前の URL について報告されます。新しい URL については、新しいモニタリングが開始されます。

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

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

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

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

  • 最初の問題は、URL の更新前にペイントが発生すると、ソフト ナビゲーションが発生する前に interaction-contentful-paint エントリが出力される可能性があることです。このような場合、navigationId は古い URL になります。URL が最初に更新された場合、ペイントによってソフト ナビゲーションが完了します。その場合、soft-navigation エントリが最初に生成され、interaction-contentful-paint に新しい URL が設定されます。
  • 2 つ目の問題は、interaction-contentful-paint の場合、新しいインタラクションのエントリが引き続き出力されることです。これは、このパフォーマンス指標のスコープが、ソフト ナビゲーションの LCP だけにとどまらないためです。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 を取得する

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

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

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

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

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

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

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

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

同様に、これらの長期間の指標の新しいソフト ナビゲーションの指標の測定を開始するときは、指標を「リセット」または「再初期化」し、以前の「ページ」に設定された値のメモリを持たない新しい指標として扱う必要があります。つまり、「最大」の描画、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 を測定する

すべてのニュアンスを考慮する最も簡単な方法は、web-vitals JavaScript ライブラリを使用することです。このライブラリは、v6.0.0 以降でソフト ナビゲーションをサポートしています。これは、次の方法で測定できます(doTraditionalProcessing と doSoftNavProcessing は適宜置き換えてください)。

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 ライブラリは、navigationId と navigationURL の両方をコールバックに提供されるエントリに含めることで、前述のとおり、指標が正しい URL に対して報告されるようにします。

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

指標 詳細
TTFB 0 として報告されます。
FCP ソフト ナビゲーションをトリガーしたインタラクションから、ソフト ナビゲーションの開始時間を基準とした First Contentful Paint の時間。前回のナビゲーションから存在する既存のペイントや、インタラクションに関連付けられていないペイントは考慮されません。
LCP ソフト ナビゲーションをトリガーしたインタラクションから、ソフト ナビゲーションの開始時間を基準とした Largest Contentful Paint の時間。以前のナビゲーションから存在する既存のペイントは、インタラクションに関連付けられていないため、考慮されません。通常どおり、ページ(またはソフト ナビゲーション)から移動するまで、この更新は継続されます。LCP が確定するのは、その時点のみです。
INP ナビゲーション時間間の INP。通常どおり、ページ(またはソフト ナビゲーション)から移動するまで、この更新は続行されます。INP が確定されるのは、その時点のみです。インタラクションがない場合、0 の値はレポートされません。ソフト ナビゲーションを発生させるインタラクションは、通常、新しいナビゲーション(ナビゲーション先)ではなく、前のナビゲーション(ナビゲーション元)に関連付けられます。これは、ソフト ナビゲーションを発生させるには最初のペイントが必要になるためです。これは、リンクのクリックに INP が関連付けられているものの、クリックが発生したページに関連付けられているハード ナビゲーションに似ています。
CLS ナビゲーション時間間のシフトの最大ウィンドウ。通常どおり、ページ(またはソフト ナビゲーション)から移動するまで更新が続けられます。CLS が確定するのは、移動したときのみです。ナビゲーション イベントに関連付けられた CLS は、インタラクションから 500 ミリ秒以内に発生した場合は除外される可能性があります。また、URL が更新される前にシフトが発生した場合は、前のナビゲーションに関連付けられる可能性があります。ソフト ナビゲーションが完了した後にシフトが発生した場合は、新しいナビゲーションに関連付けられる可能性があります。

これらの変更は Core Web Vitals の測定に含まれますか?

最終的な目標は、実際のユーザーが体験するパフォーマンスをより適切に測定する手段を提供することです。そのため、API のリリース後にすべてのツールで公開される Core Web Vitals の測定に、これらの指標を含めることを目指しています。

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

CrUX で Core Web Vitals 指標の試験運用版をリリースしました。これらは、最初のソフト ナビゲーション後に「ハード ナビゲーション」の CLS と INP を終了し、各ソフト ナビゲーションの追加の LCP、CLS、INP 測定値も含みます。これらの試験運用版の指標は、2027 年 5 月に安定版の指標に移行する予定です。詳細については、試験運用版のソフト ナビゲーション指標が CrUX で利用可能にのブログ投稿をご覧ください。

他のブラウザでソフト ナビゲーションを処理する方法

API をサポートしていないブラウザでは、ソフト ナビゲーションをプログラムで検出することは困難です。この API の開発に取り組んだのは、まさにこのためです。

Navigation API を使用して URL の変更をモニタリングし、URL ごとに INP をスライスできます(CLS も同様ですが、現時点では Chromium のみであるため、測定されません)。ただし、この方法では、近似値しか得られないペイント指標(FCP と LCP)には対応できません。

同時に、この API が提供する分析情報は、ソフト ナビゲーションのタイミングの測定と、指標を正しいナビゲーションに関連付けることの両方において、無視できないほど価値があると考えています。現時点ではクロスブラウザ サポートがありませんが、この新しい API を使用することをおすすめします。Core Web Vitals のリリース時と同様に、特定された問題とパフォーマンス ソリューションは、現時点では Chromium ベースのブラウザに限定されているものの、すべてのブラウザに影響する可能性があります。

Google は引き続き標準化プロセスに取り組み、他のブラウザ ベンダーと連携して、この API の重要性を示していきます。

フィードバック

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

どちらに報告すべきか迷った場合でも、心配する必要はありません。どちらの場所でもフィードバックを受け付けており、両方の場所で問題をトリアージして、正しい場所に問題をリダイレクトします。

変更履歴

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

まとめ

ソフト ナビゲーション機能は、Core Web Vitals イニシアチブがどのように進化して、Google の指標に欠けている最新のウェブの一般的なパターンを測定できるかという点において、興味深いアプローチです。Google は、幅広いウェブ コミュニティから多くのフィードバックを収集しており、この API の可能性に期待を寄せています。

謝辞

サムネイル画像: Jordan Madrid(Unsplash)

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