Web ページパフォーマンスとユーザー体験分析¶
Web RUM SDK は、実ユーザーがページにアクセスした際のロード、レンダリング、インタラクション、レイアウト変化、エラー、リソース、ロングタスクのデータを、同一の view_id に関連付けます。アプリケーションデータが Guance に送信された後、まず Core Web Vitals で全体的な体験を評価し、次にページ、バージョン、ブラウザ、デバイス、ネットワークなどの軸で影響範囲を特定し、最後に view_id に沿ってエラー、リソース、ロングタスク、セッションリプレイにドリルダウンします。
本記事のすべてのフィールド名は、Web RUM SDK が現在報告するデータ構造に基づいています。完全なフィールド一覧は Web アプリケーションデータ収集 を参照してください。
分析前の統計口径の明確化¶
初回ロードとルート遷移の区別¶
view_loading_type は、2 種類の View を区別するために使用されます。
initial_load:ブラウザが初めてページを開くか、リフレッシュした場合。route_change:シングルページアプリケーション(SPA)でルート遷移が発生した場合。
現在の SDK は、initial_load View でのみ first_byte、first_contentful_paint、largest_contentful_paint、first_input_delay およびナビゲーションタイミングフィールドを収集します。loading_time、interaction_to_next_paint、cumulative_layout_shift および View 関連のカウントは、initial_load と route_change の両方に適用されます。
したがって:
- ファーストビュー、ホワイトスクリーン候補、FCP、LCP、
TTFBを分析する場合は、view_loading_type = "initial_load"でフィルタリングする必要があります。 - SPA ルートのパフォーマンスを分析する場合は、
loading_time、interaction_to_next_paint、cumulative_layout_shift、エラー、ロングタスクなどのフィールドを優先的に使用します。 route_changeに FCP や LCP がないレコードを異常と判断しないでください。
P75 の使用:平均値だけを見ない¶
Core Web Vitals は、ページアクセスサンプルの第 75 パーセンタイル(P75)を使用した評価と、モバイル端末とデスクトップ端末をそれぞれ観察することを推奨しています。P75 が基準を満たしているということは、少なくとも 75% のページアクセスが目標範囲内にあることを意味します。平均値は、多数の高速なサンプルに希釈されやすく、低速ユーザーの実際の体験を表すことができません。
以下の項目も同時に観察することを推奨します。
- P50:典型的なユーザー体験。
- P75:Core Web Vitals の主要な判断基準。
- P90 または P95:低速ネットワーク、低パフォーマンスデバイスなどのテールユーザー体験。
- 達成率:「良好」な閾値内にある View の数が有効サンプル数に占める割合。
- サンプル数:少数のサンプルに基づいてページやバージョンの品質を判断しないようにする。
指標の定義、閾値、P75 の統計方法については、web.dev:Web Vitals と 実環境における Web Vitals 統計のベストプラクティス を参照してください。
単位に注意¶
cumulative_layout_shiftを除き、この記事に記載されている時間指標は、データ内ではナノ秒(ns)で保存されます。1s = 1,000,000,000ns、1ms = 1,000,000ns。cumulative_layout_shiftは無単位のスコアであり、時間換算しないでください。- DQL の閾値は、元の保存単位を使用する必要があります。例えば、LCP 2.5 秒は
2500000000と記述します。
コアエクスペリエンス指標¶
Core Web Vitals¶
| 体験の軸 | SDK フィールド | 有効な View | 良好 | 改善が必要 | 不良 | 特定用フィールド |
|---|---|---|---|---|---|---|
| ロードパフォーマンス(LCP) | largest_contentful_paint |
initial_load |
≤ 2.5s | > 2.5s かつ ≤ 4s | > 4s | largest_contentful_paint_element_selector |
| インタラクション応答性(INP) | interaction_to_next_paint |
initial_load、route_change |
≤ 200ms | > 200ms かつ ≤ 500ms | > 500ms | interaction_to_next_paint_target_selector |
| 視覚的安定性(CLS) | cumulative_layout_shift |
initial_load、route_change |
≤ 0.1 | > 0.1 かつ ≤ 0.25 | > 0.25 | cumulative_layout_shift_target_selector |
LCP、INP、CLS の閾値は、それぞれ LCP、INP、CLS を参照してください。
LCP:ユーザーがいつメインコンテンツを確認できるか¶
largest_contentful_paint は、ビューポート内で最大の画像、テキストブロック、またはビデオの描画が完了した時間を示します。SDK は同時に largest_contentful_paint_element_selector を報告し、LCP を生成したページ要素を特定するために使用します。
LCP が不良の場合、以下のフィールドを組み合わせて、時間消費がどの区間で発生しているかを判断します。
first_byteが高い場合:サーバー応答、リダイレクト、CDN、地域、ネットワークを優先的に確認します。first_byteは正常だがfirst_contentful_paintが高い場合:レンダリングをブロックする CSS、JavaScript、クライアント側の初期化を優先的に確認します。first_contentful_paintは正常だがlargest_contentful_paintが高い場合:LCP 要素に対応するリソースの発見が遅すぎる、ダウンロードが遅すぎる、またはレンダリングが遅延していないかを優先的に確認します。loading_timeが LCP よりも明らかに高い場合:ページのメインコンテンツは既に表示されているが、ネットワークリクエストや DOM の変更が継続して発生している可能性があります。
INP:ページが操作に迅速に応答できるか¶
interaction_to_next_paint は、1 回のインタラクションにおける、入力からイベント処理、次のフレーム描画までの完全なレイテンシを測定します。SDK は View 内でインタラクションを継続的に観察し、最悪に近いインタラクションの値を報告すると同時に、interaction_to_next_paint_target_selector で対応する要素を特定します。
INP が不良の場合、以下に重点的に関連付けます。
view_long_task_count:メインスレッドを 50ms 以上ブロックするタスクがページに存在するか。view_error_count:インタラクション中にスクリプトエラーが発生したか。frustration_count:繰り返しクリック、無効なクリック、誤ったクリックなどのフラストレーション行動が発生したか。R::long_taskのduration、blocking_duration、scripts:ブロック時間と関連スクリプトを特定します。
ユーザーインタラクションがない View には interaction_to_next_paint が存在しない可能性があります。INP を統計する際は、このフィールドが存在するサンプルのみを使用します。
CLS:ページコンテンツが予期せず移動していないか¶
cumulative_layout_shift は、ページの表示要素の予期しない移動を測定し、cumulative_layout_shift_target_selector は、最大の影響を与えた要素を指します。
CLS が不良の場合、一般的な確認項目は以下のとおりです。
- 画像、ビデオ、広告、
iframeに幅と高さが予約されていない。 - 非同期コンテンツが既存のコンテンツの上に挿入されている。
- Web フォントの切り替えによりテキストサイズが変化する。
- アニメーションがレイアウトをトリガーするプロパティを使用して実装されている。
初回ロード補助指標¶
| SDK フィールド | 意味 | 推奨用途 |
|---|---|---|
first_byte |
ナビゲーション開始からドキュメント応答の最初のバイトを受信するまで | サーバー、ネットワーク、リダイレクト、CDN が後続のレンダリングを遅延させていないか判断 |
first_contentful_paint |
最初のテキスト、画像、SVG、または非白色 Canvas の描画時間 | ユーザーが最初にコンテンツを確認するタイミングを測定。ホワイトスクリーン候補分析の主要フィールドでもある |
dom_interactive |
ドキュメントパーサーが解析を完了した時点 | HTML と同期スクリプトが DOM のインタラクティブ状態を遅延させていないか判断 |
dom_content_loaded |
DOMContentLoaded 完了時点 |
DOM 構築と遅延スクリプトの完了時間を判断 |
dom_complete |
ページとサブリソースが完了した時点 | 完全なドキュメントライフサイクルが長すぎないか判断 |
load_event |
load イベント完了時点 |
依存リソースの全ロード完了時間を判断 |
first_paint_time |
現在の SDK が計算する responseEnd - fetchStart |
ドキュメント応答フェーズの所要時間を観察。これを FCP と同一視しないでください |
time_to_interactive |
現在の SDK が計算する domInteractive - fetchStart |
DOM がインタラクティブ状態に達する時間を観察。ラボツールの TTI と混同しないでください |
dom_ready |
現在の SDK が計算する domContentLoadedEventEnd - fetchStart |
DOM Ready 完了までの所要時間を観察 |
resource_load_time |
現在の SDK が計算する loadEventStart - domContentLoadedEventEnd |
DOM Ready 後に依存リソースを待機する所要時間を観察 |
dom |
現在の SDK が計算する domComplete - domInteractive |
DOM がインタラクティブになってから完全に完了するまでの所要時間を観察 |
FCP については、web.dev:FCP を参照してください。良好は 1.8 秒以内、不良は 3 秒を超える場合です。first_byte については、web.dev:最初のバイトまでの時間 を参照してください。0.8 秒以内は通常良好で、1.8 秒を超えると通常不良です。TTFB は Core Web Vitals ではないため、FCP と LCP を組み合わせて判断する必要があります。
ページロードと使用体験指標¶
| SDK フィールド | 意味 | 回答に適した質問 |
|---|---|---|
loading_time |
SDK が load イベント、ネットワークリクエスト、DOM アクティビティを総合して算出したページ安定までの所要時間 |
ページの主要なロードアクティビティがいつ終了するか。SPA ルート遷移がリクエストや DOM 更新を継続しているか |
time_spent |
ユーザーが現在の View に滞在した時間 | 遅いページが早期離脱を引き起こしていないか。異常が長時間の使用に影響を与えていないか |
view_error_count |
現在の View に関連付けられたエラー数 | ページがスクリプトエラーにより使用不可になっていないか |
view_resource_count |
現在の View に関連付けられたリソースリクエスト数 | ページがリクエストしすぎていないか。リソースのウォーターフォール分析を継続する必要があるか |
view_long_task_count |
現在の View に関連付けられたロングタスク数 | メインスレッドが頻繁にブロックされていないか |
view_action_count |
現在の View に関連付けられたユーザー操作数 | ページが実際に使用されているか。INP サンプルがないのはインタラクションがないためか |
frustration_count |
現在の View に関連付けられたフラストレーション行動の数 | ユーザーが応答なし、結果なし、またはエラーのために操作を繰り返していないか |
is_active |
View がまだアクティブな状態か | まだ終了しておらず、指標が引き続き更新される可能性がある View をフィルタリング |
session_has_replay |
現在のセッションに関連するセッションリプレイがあるか | 異常ユーザーの状況を直接リプレイできるか |
loading_time は視覚的な完了時間と同等ではありません。ページは先に LCP を完了できますが、バックグラウンドポーリング、API リクエスト、継続的な DOM 更新により loading_time が長くなる可能性があります。逆に、loading_time が正常でも、ページのメインコンテンツが正しく表示されていることを証明するものではありません。
ページパフォーマンスのベースライン構築¶
ステップ 1:各ページの P75 を確認する¶
以下のクエリはダッシュボードチャート向けであり、DQL 内に [24h]、[1h] などの固定時間範囲を意図的に記述していません。時間範囲を省略すると、クエリはダッシュボード右上の時間ウィジェットに従います。DQL 内で直接時間範囲を指定した場合、その優先順位はダッシュボードの時間ウィジェットよりも高くなり、グラフはその時間帯を固定でクエリします。詳細については、DQL 時間範囲指定 を参照してください。<APP_ID> をアプリケーション ID に置き換えてください。
ページごとに LCP P75 を表示:
R::view:(percentile(largest_contentful_paint, 75) AS p75_lcp) {app_id = "<APP_ID>", view_loading_type = "initial_load", largest_contentful_paint = exists()} BY view_path_group SORDER BY p75_lcp DESC SLIMIT 20
ページごとに INP P75 を表示:
R::view:(percentile(interaction_to_next_paint, 75) AS p75_inp) {app_id = "<APP_ID>", interaction_to_next_paint = exists()} BY view_path_group SORDER BY p75_inp DESC SLIMIT 20
ページごとに CLS P75 を表示:
R::view:(percentile(cumulative_layout_shift, 75) AS p75_cls) {app_id = "<APP_ID>", cumulative_layout_shift = exists()} BY view_path_group SORDER BY p75_cls DESC SLIMIT 20
3 つの指標を直接合計してスコアにしないでください。LCP、INP、CLS はそれぞれロード、応答性、安定性を表しており、いずれかが不良な場合は個別に特定する必要があります。
ステップ 2:達成率を観察する¶
以下のクエリは、LCP が 2.5 秒以内である有効な View の割合を計算します。
eval(100 * A / B, alias='LCP_good_rate', A="R::view:(count(view_id)) {app_id = '<APP_ID>', view_loading_type = 'initial_load', largest_contentful_paint <= 2500000000}", B="R::view:(count(view_id)) {app_id = '<APP_ID>', view_loading_type = 'initial_load', largest_contentful_paint = exists()}")
同様に、条件を以下に置き換えることもできます。
- INP 達成:
interaction_to_next_paint <= 200000000。 - CLS 達成:
cumulative_layout_shift <= 0.1。 - FCP 達成:
first_contentful_paint <= 1800000000。
分母は、指標が存在する有効なサンプルのみをカウントする必要があります。そうしないと、この指標をサポートしていないブラウザ、インタラクションのない View、早期に離脱した View によって結果が歪められます。
ステップ 3:主要な軸で分割する¶
以下の SDK フィールドを順に使用してグループ化またはフィルタリングすることを推奨します。
view_path_group:最初に影響を受けるページを特定します。version:新しいバージョンによるリグレッションかどうかを判断します。browser、browser_version_major:ブラウザの互換性や機能の違いを判断します。device、screen_size:デバイスのパフォーマンスとレイアウトの違いを区別します。network_type:Wi-Fi、セルラーネットワーク、到達不能なネットワークを区別します。env、service:異なる環境やサービスのデータが混在するのを避けます。
例えば、バージョンとページごとに Core Web Vitals を比較する場合:
R::view:(percentile(largest_contentful_paint, 75) AS p75_lcp, percentile(interaction_to_next_paint, 75) AS p75_inp, percentile(cumulative_layout_shift, 75) AS p75_cls) {app_id = "<APP_ID>"} BY version, view_path_group SORDER BY p75_lcp DESC SLIMIT 50
LCP は initial_load にのみ存在し、INP はインタラクションがないために欠落する可能性があるため、本番ダッシュボードでは、3 つの指標それぞれにグラフを作成し、同じページ、バージョン、デバイスのフィルター条件で連携して分析することを推奨します。
ホワイトスクリーンと長時間無内容の分析¶
ホワイトスクリーンは SDK の直接的な指標ではない¶
現在の SDK は、white_screen という名前のフィールドを報告しません。ホワイトスクリーンは、収集済みの指標から候補セットを構築し、エラー、リソース、ロングタスク、セッションリプレイを組み合わせて確認する必要があります。
候補を 2 つのレベルに分類することを推奨します。
- 遅い FCP 候補:
first_contentful_paint > 3000000000。ユーザーが最初のコンテンツを確認するまでに 3 秒以上かかったことを示し、比較的安定して統計可能なホワイトスクリーン体験の近似値です。 - FCP 欠落候補:終了した初回ロード View で、滞在時間が 3 秒を超えているが、
first_contentful_paintが存在しない場合。このルールは調査目的でのみ使用でき、ホワイトスクリーンと直接同一視することはできません。
FCP の欠落は、以下の状況によっても発生する可能性があります。
- 現在のブラウザが SDK で使用されている FCP 収集機能をサポートしていない。
- FCP が生成される前にページがバックグラウンドに入ったか、非表示になった。
- ユーザーがページを事前に閉じた。
- データサンプリング、ネットワークレポート、またはページライフサイクルが早期に終了した。
- 誤って
route_changeを分析に含めた。
したがって、FCP 欠落ルールは、view_loading_type = "initial_load" でフィルタリングし、browser ごとに収集カバレッジを検証する必要があります。ブラウザの機能の境界については、Browser Support を参照してください。
遅い FCP 候補の割合を統計する¶
eval(100 * A / B, alias='white_screen_candidate_rate', A="R::view:(count(view_id)) {app_id = '<APP_ID>', view_loading_type = 'initial_load', first_contentful_paint > 3000000000}", B="R::view:(count(view_id)) {app_id = '<APP_ID>', view_loading_type = 'initial_load', first_contentful_paint = exists()}")
この割合は、「有効な FCP サンプルのうち、コンテンツを確認するまでに 3 秒以上かかった割合」を示し、視覚的に確認された実際のホワイトスクリーン率を示すものではありません。さらに、view_path_group、version、browser、network_type で分割することを推奨します。
遅い FCP View を特定する¶
R::view:(view_id, session_id, view_url, first_contentful_paint, first_byte, loading_time, view_error_count, view_resource_count, view_long_task_count, session_has_replay) {app_id = "<APP_ID>", view_loading_type = "initial_load", first_contentful_paint > 3000000000} ORDER BY first_contentful_paint DESC LIMIT 100
結果の解釈:
first_byteも非常に高い場合:サーバー、CDN、ネットワーク、リダイレクトを優先的に確認します。first_byteは正常だが FCP が非常に高い場合:レンダリングをブロックするリソース、クライアントサイドレンダリング、同期 JavaScript を優先的に確認します。view_error_count > 0:エラースタックトレースを優先的に確認し、初期化が中断されていないか確認します。view_long_task_count > 0:最初の描画前にメインスレッドがロングタスクによってブロックされていないか確認します。session_has_replay = true:session_idまたはview_idを使用してセッションリプレイを開き、ユーザーが実際に確認した画面を確認します。
FCP 欠落候補を特定する¶
R::view:(view_id, session_id, view_url, time_spent, view_error_count, view_resource_count, view_long_task_count, session_has_replay) {app_id = "<APP_ID>", view_loading_type = "initial_load", is_active = false, time_spent > 3000000000, first_contentful_paint != exists()} ORDER BY time_spent DESC LIMIT 100
この結果は、まず browser ごとに FCP をサポートしていないサンプルを除外し、その後、セッションリプレイとドリルダウンクエリを組み合わせて確認する必要があります。FCP 欠落のみに基づいて「実際のホワイトスクリーン率」のアラートを作成しないでください。
view_id に沿って根本原因にドリルダウンする¶
候補結果の <VIEW_ID> を以下のクエリに代入します。
スクリプトとランタイムエラーを表示:
R::error:(error_type, error_source, error_message, error_stack) {app_id = "<APP_ID>", view_id = "<VIEW_ID>"} ORDER BY time ASC LIMIT 100
失敗したリソースまたは低速なリソースを表示:
R::resource:(resource_url, resource_type, resource_status, duration, resource_ttfb, resource_trans) {app_id = "<APP_ID>", view_id = "<VIEW_ID>", resource_status >= 400} ORDER BY duration DESC LIMIT 100
HTTP エラーがない場合でも、リソースが遅すぎる可能性がある場合は、resource_status >= 400 を削除し、duration で最も遅いリソースを表示できます。resource_ttfb が高い場合は通常、サーバー側またはネットワーク待機を示し、resource_trans が高い場合は通常、コンテンツ転送時間を示します。
ロングタスクを表示:
R::long_task:(duration, blocking_duration, scripts) {app_id = "<APP_ID>", view_id = "<VIEW_ID>"} ORDER BY duration DESC LIMIT 100
duration はロングタスクの合計時間を示し、blocking_duration はそのうちユーザー入力をブロックした時間を示し、scripts は関連スクリプトを特定するために使用できます。
一般的な体験問題の判断パス¶
| 現象 | 最初に確認するフィールド | さらに連携する項目 | 一般的な方向性 |
|---|---|---|---|
| ページにコンテンツが表示されない | first_contentful_paint、first_byte |
view_error_count、view_long_task_count、Resource |
サーバー側の遅延、レンダリングブロック、初期化エラー、ロングタスク |
| メインコンテンツのロードが遅い | largest_contentful_paint |
largest_contentful_paint_element_selector、Resource |
LCP リソースの発見遅延、ダウンロード低速、レンダリング遅延 |
| クリック後に応答がない | interaction_to_next_paint |
interaction_to_next_paint_target_selector、Long Task、Error |
メインスレッドブロック、イベント処理の過負荷、スクリプトエラー |
| ページコンテンツが動く | cumulative_layout_shift |
cumulative_layout_shift_target_selector |
サイズ未予約、動的挿入、フォントとアニメーション |
| ページがロード中のまま | loading_time |
Resource、DOM アクティビティ、Error | リクエスト未完了、ポーリング、継続的 DOM 更新、異常状態の収束なし |
| ユーザーが繰り返しクリックする、またはクリックに反応がない | frustration_count |
Action、INP、Error、セッションリプレイ | 視覚的フィードバックなし、無効なクリック、誤ったクリック、遅いインタラクション |
| 新しいバージョンで体験が低下 | version + P75 |
view_path_group、browser、network_type |
リソースサイズ、コードパス、互換性、またはリリースによるリグレッション |
ダッシュボードとアラートの推奨事項¶
少なくとも以下のビューを作成することを推奨します。
- LCP、INP、CLS の P75 トレンドと達成率。
- FCP、
first_byte、loading_timeの P75 トレンド。 view_path_groupでソートされた低速ページ Top 20。versionで比較したリリース前後のトレンド。browser、device、network_type、地域で分割したテール体験。view_error_count、view_long_task_count、frustration_countとパフォーマンス指標の関連グラフ。- 遅い FCP 候補の割合とリプレイ可能なサンプルリスト。
アラートは、P75 または達成率を優先的に使用し、最小サンプル数と連続トリガー条件を設定して、少数の異常サンプルや短時間のトラフィック変動による誤報を回避する必要があります。Core Web Vitals の「不良」閾値から開始し、ビジネスページの重要度、過去のベースライン、実際のトラフィックに基づいて調整することを推奨します。
コンソールでの分析の完了¶
- 「ユーザーアクセス監視 > 分析ダッシュボード > Web 端末」で、概要、ページパフォーマンス、リソース、エラー分析を表示します。
- 「ユーザーアクセス監視 > エクスプローラー」で、
view_id、session_id、ページ、バージョン、ブラウザで元の View をフィルタリングします。 - 個々の View に入った後、Resource、Error、Long Task、Action、セッションリプレイを関連付けて表示します。
- カスタム統計が必要な場合は、本記事の DQL を使用してダッシュボードチャートまたはユーザーアクセス指標検出を作成します。
コンソールの詳細については、分析ダッシュボード、エクスプローラー、ユーザーアクセス指標検出 を参照してください。