パフォーマンス データにデバッグ情報を関連付けて、分析で実際のユーザーの問題を特定して修正する方法について学びます。
Google では、パフォーマンスの測定とデバッグのためのツールとして、次の 2 つのカテゴリを提供しています。
- ラボツール: Lighthouse などのツール。さまざまな条件(ネットワークの遅延や低価格のモバイル デバイスなど)を模倣できるシミュレートされた環境でページが読み込まれます。
- フィールドツール: Chrome の実際のユーザーの集計データに基づく Chrome ユーザー エクスペリエンス レポート(CrUX)などのツール。(PageSpeed Insights や Search Console などのツールによってレポートされるフィールド データは、CrUX データから収集されたものです)。
フィールド ツールは、実際のユーザー エクスペリエンスを実際に表すより正確なデータを提供しますが、ラボツールは、問題の特定と修正に役立つことがよくあります。
CrUX データはページの実際のパフォーマンスをよりよく表しますが、CrUX スコアを知っても、パフォーマンスを改善する方法を把握することはできません。
一方、Lighthouse では、問題を特定し、具体的な改善案を提示します。ただし、Lighthouse で提案されるのは、ページの読み込み時に検出されたパフォーマンスの問題のみです。ページのスクロールやボタンのクリックなどのユーザー操作の結果としてのみ発生する問題は検出されません。
ここで重要な問題が浮かびます。Core Web Vitals やその他のパフォーマンス指標のデバッグ情報を、実際のユーザーから収集するにはどうすればよいですか?
この投稿では、現在の Core Web Vitals の各指標に関する追加のデバッグ情報を収集するために使用できる API について詳しく説明します。また、既存の分析ツールでこのデータを取得する方法についても説明します。
アトリビューションとデバッグ用の API
Cumulative Layout Shift(CLS)
Core Web Vitals のすべての指標の中で、CLS はおそらく、現場のデバッグ情報の収集が最も重要となる指標でしょう。CLS はページ全体を通して測定されるため、ユーザーによるページ操作方法(スクロール距離、クリックなど)が、レイアウト シフトの有無やシフトする要素に大きな影響を与える可能性があります。
PageSpeed Insights の次のレポートについて考えてみましょう。
ラボの CLS についてレポートされる値(Lighthouse)と、フィールドの CLS の値(CrUX データ)はかなり異なるため、Lighthouse でのテストでは使用されないインタラクティブなコンテンツがページ内にたくさんあることを考えると、これは当然のことです。
ただし、ユーザー操作がフィールドデータに影響することを理解していても、75 パーセンタイル スコアが 0.28 になるようにページ上のどの要素がシフトしているかを把握する必要があります。これは LayoutShiftAttribution インターフェースによって可能になります。
レイアウト シフトのアトリビューションを取得する
LayoutShiftAttribution インターフェースは、Layout Instability API が出力する各 layout-shift
エントリで公開されます。
両方のインターフェースの詳細については、レイアウト シフトをデバッグするをご覧ください。この投稿で知っておくべき主なことは、デベロッパーは、ページ上で発生するすべてのレイアウト シフトと、シフトされる要素を監視できることです。
次のサンプルコードは、各レイアウト シフトとシフトした要素をログに記録しています。
new PerformanceObserver((list) => {
for (const {value, startTime, sources} of list.getEntries()) {
// Log the shift amount and other entry info.
console.log('Layout shift:', {value, startTime});
if (sources) {
for (const {node, curRect, prevRect} of sources) {
// Log the elements that shifted.
console.log(' Shift source:', node, {curRect, prevRect});
}
}
}
}).observe({type: 'layout-shift', buffered: true});
発生するレイアウト シフトごとにデータを測定してアナリティクス ツールに送信することは現実的ではありませんが、すべてのシフトをモニタリングすることで、最も大きなシフトを追跡し、それに関する情報のみをレポートできます。
目標は、すべてのユーザーで発生するレイアウト シフトをすべて特定して修正することではなく、最も多くのユーザーに影響し、75 パーセンタイル時のページの CLS に最も大きく貢献するシフトを特定することです。
また、シフトが発生するたびに最大のソース要素を計算する必要はなく、CLS 値を分析ツールに送信する準備ができた場合にのみ計算する必要があります。
次のコードは、CLS の原因となった layout-shift
エントリのリストを取得し、最大のシフトから最大のソース要素を返します。
function getCLSDebugTarget(entries) {
const largestEntry = entries.reduce((a, b) => {
return a && a.value > b.value ? a : b;
});
if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
const largestSource = largestEntry.sources.reduce((a, b) => {
return a.node && a.previousRect.width * a.previousRect.height >
b.previousRect.width * b.previousRect.height ? a : b;
});
if (largestSource) {
return largestSource.node;
}
}
}
最大の変化に大きく貢献している要素を特定したら、それを分析ツールに報告できます。
あるページで CLS に最も大きく寄与している要素はユーザーによって異なる可能性がありますが、すべてのユーザーからこれらの要素を集約すると、最も多くのユーザーに影響を与える要素のリストを生成できます。
これらの要素のシフトの根本原因を特定して修正すると、小さなシフトがページの「最悪の」シフトとしてアナリティクス コードでレポートされるようになります。最終的には、レポートされる変化はすべて小さくなり、ページが「良好」しきい値の 0.1 に十分収まるようになります。
最大のシフトソース要素とともにキャプチャすると役立つ可能性のあるその他のメタデータは次のとおりです。
- 最大シフトの時間
- 最大シフト時の URL パス(シングルページ アプリケーションなど、URL を動的に更新するサイトの場合)。
Largest Contentful Paint(LCP)
該当フィールドの LCP をデバッグするには、まずどの要素がそのページの読み込みで最大の要素(LCP 候補要素)であるかを把握する必要があります。
同じページでも、LCP 候補要素がユーザーによって異なることは十分にあり得ます(実際、非常に一般的です)。
この問題は次のような原因で発生することがあります。
- ユーザーのデバイスの画面解像度が異なるため、ページのレイアウトが異なり、ビューポート内に表示される要素も異なります。
- ユーザーがページを一番上までスクロールして読み込むとは限りません。多くの場合、リンクにはフラグメント識別子やテキスト フラグメントが含まれます。つまり、ページのどのスクロール位置でもページが読み込まれ、表示される可能性があります。
- コンテンツは現在のユーザーに合わせてパーソナライズされる場合があるため、LCP の候補要素はユーザーごとに大きく異なる可能性があります。
つまり、どの要素または要素のセットが、特定のページで最も一般的な LCP 候補要素になるかを予測することはできません。実際のユーザー行動に基づいて測定する必要があります。
LCP 候補要素を特定する
JavaScript で LCP 候補要素を特定するには、Largest Contentful Paint API を使用します。これは、LCP 時間値の特定に使用するのと同じ API です。
largest-contentful-paint
エントリを監視している場合、最後のエントリの element
プロパティを調べることで、現在の LCP 候補要素を特定できます。
new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});
LCP 候補要素を特定したら、それを指標値とともに分析ツールに送信できます。CLS と同様に、最初に最適化すべき要素を特定するのに役立ちます。
LCP 候補要素に加えて、LCP サブパート時間を測定すると、サイトに関連する具体的な最適化手順を判断するのに役立ちます。
Interaction to Next Paint(INP)
INP の現場で収集すべき最も重要な情報は次のとおりです。
- 操作された要素
- そのインタラクションの種類
- そのやり取りが行われた日時
インタラクションが遅い主な原因は、メインスレッドがブロックされることです。これは、JavaScript の読み込み中によく発生します。ほとんどの遅いインタラクションが発生するのはページの読み込み中かどうかを把握することは、問題を解決するために必要なことを判断するうえで役立ちます。
INP 指標は、インタラクションの完全なレイテンシ(登録済みのイベント リスナーの実行にかかる時間や、すべてのイベント リスナーの実行後に次のフレームの描画にかかった時間など)を考慮します。つまり、INP では、インタラクションの遅延につながる傾向のあるターゲット要素と、そのインタラクションの種類を把握することが非常に重要です。
次のコードは、INP エントリのターゲット要素と時間をログに記録します。
function logINPDebugInfo(inpEntry) {
console.log('INP target element:', inpEntry.target);
console.log('INP interaction type:', inpEntry.name);
console.log('INP time:', inpEntry.startTime);
}
このコードでは、どの event
エントリが INP エントリであるかを判断する方法は示していません。このロジックは複雑であるためです。次のセクションでは、web-vitals JavaScript ライブラリを使用してこの情報を取得する方法について説明します。
web-vitals JavaScript ライブラリの使用
前のセクションでは、分析ツールに送信するデータに含めるデバッグ情報をキャプチャするための一般的なヒントとコード例を紹介しました。
バージョン 3 以降、web-vitals JavaScript ライブラリには、これらの情報をすべて表面化させるアトリビューション ビルドと、いくつかの追加シグナルが含まれています。
パフォーマンスの問題の根本原因の特定に役立つデバッグ文字列を含む追加のイベント パラメータ(またはカスタム ディメンション)を設定する方法を、次のコード例に示します。
import {onCLS, onINP, onLCP} from 'web-vitals/attribution';
function sendToGoogleAnalytics({name, value, id, attribution}) {
const eventParams = {
metric_value: value,
metric_id: id,
}
switch (name) {
case 'CLS':
eventParams.debug_target = attribution.largestShiftTarget;
break;
case 'LCP':
eventParams.debug_target = attribution.element;
break;
case 'INP':
eventParams.debug_target = attribution.interactionTarget;
break;
}
// Assumes the global `gtag()` function exists, see:
// https://developers.google.com/analytics/devguides/collection/ga4
gtag('event', name, eventParams);
}
onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);
このコードは Google アナリティクスに固有のものですが、基本的な考え方は他の分析ツールにも応用できます。
このコードでは、1 つのデバッグ シグナルに関するレポートを作成する方法も示されていますが、指標ごとに複数の異なるシグナルを収集してレポートできると便利です。
たとえば、INP をデバッグするには、操作している要素、操作タイプ、時間、loadState、操作フェーズなど(Long Animation Frame Data など)を収集します。
次の例の INP に示すように、web-vitals
アトリビューション ビルドは追加のアトリビューション情報を公開します。
import {onCLS, onINP, onLCP} from 'web-vitals/attribution';
function sendToGoogleAnalytics({name, value, id, attribution}) {
const eventParams = {
metric_value: value,
metric_id: id,
}
switch (name) {
case 'INP':
eventParams.debug_target = attribution.interactionTarget;
eventParams.debug_type = attribution.interactionType;
eventParams.debug_time = attribution.interactionTime;
eventParams.debug_load_state = attribution.loadState;
eventParams.debug_interaction_delay = Math.round(attribution.inputDelay);
eventParams.debug_processing_duration = Math.round(attribution.processingDuration);
eventParams.debug_presentation_delay = Math.round(attribution.presentationDelay);
break;
// Additional metric logic...
}
// Assumes the global `gtag()` function exists, see:
// https://developers.google.com/analytics/devguides/collection/ga4
gtag('event', name, eventParams);
}
onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);
公開されるデバッグ シグナルの一覧については、web-vitals アトリビューションのドキュメントをご覧ください。
データをレポートして可視化する
指標値とともにデバッグ情報の収集を開始したら、次のステップは、すべてのユーザーのデータの集計です。これにより、パターンと傾向を探すことができます。
前述のように、ユーザーが直面しているすべての問題に必ずしも対処する必要はありません。最も多くのユーザーに影響を与えている問題、特に最初に対処すべき問題です。これらは Core Web Vitals のスコアに最大の悪影響を及ぼす問題でもあるはずです。
GA4 については、BigQuery を使用してデータをクエリして可視化する方法に関する専用の記事をご覧ください。
概要
この投稿では、既存のパフォーマンス API と web-vitals
ライブラリを使用してデバッグ情報を取得し、現場での実際のユーザーのアクセスに基づいてパフォーマンスを診断する具体的な方法について説明しました。このガイドではウェブに関する主な指標に焦点を当てていますが、ここで説明するコンセプトは、JavaScript で測定可能なパフォーマンス指標のデバッグにも適用されます。
パフォーマンスの測定を初めて行う場合で、すでに Google アナリティクスをご利用の場合は、ウェブに関する主な指標のデバッグ情報のレポートをサポートしているウェブに関する主な指標レポート ツールから始めることをおすすめします。
分析ベンダーの方は、サービスを改善し、より多くのデバッグ情報をユーザーに届けたいとお考えの場合に、ここで説明する手法の使用を検討してください。ただし、ここで説明するアイデアだけにとどまらないでください。この記事は、すべてのアナリティクス ツールに一般的に適用することを目的としています。ただし、個々のアナリティクス ツールでは、さらに多くのデバッグ情報をキャプチャして報告できる可能性があります(また、そうすべきです)。
最後に、API 自体に機能や情報が不足しているために、これらの指標のデバッグ機能に不足があると思われる場合は、web-vitals-feedback@googlegroups.com までフィードバックを送信してください。