Google アナリティクス 4 と BigQuery によるパフォーマンスの測定とデバッグ

ウェブに関する指標のデータを Google アナリティクス 4 プロパティに送信し、エクスポートして BigQuery と Looker Studio で分析する方法について説明します。

Google は、Search ConsolePageSpeed Insights(PSI)、Chrome ユーザー エクスペリエンス レポート(CrUX)などのさまざまなツールを提供しています。これらのツールを使用すると、実際のユーザーの実際のウェブに関する指標の指標に照らしてサイトのパフォーマンスを実際の環境で確認することができます。

これらのツールは、サイトの実際のユーザー パフォーマンスを大まかに把握できる点で優れています。設定は一切不要で、使い始めることができます。

ただし、いくつかの重要な理由から、これらのツールだけに頼ってサイトのパフォーマンスを測定することはおすすめしません。

  • CrUX ベースのツールは、月次または過去 28 日間のデータを報告します。つまり、変更を加えた後、結果が表示されるまでに長い時間待つ必要があります。
  • CrUX ベースのツールは、国、接続タイプ、デバイス カテゴリ(パソコンまたはモバイル)など、限られた数のディメンションでしかセグメント化できません。ビジネスに固有のディメンション(エンゲージメント ユーザー数、特定のテストグループ内のユーザーなど)でデータをスライスすることはできません。
  • CrUX ベースのツールは、パフォーマンスについてお知らせできますが、理由までは説明できません。分析ツールを使用すると、問題の追跡とデバッグに役立つ追加データを送信できます。

そのため、すべてのサイト所有者は、既存の分析ツールを使用して Core Web Vitals の指標をモニタリングすることをおすすめします。この投稿では Google が無料で提供している ツールを使ってそれを実現する方法を説明します

すべての設定が完了すると、次のようなダッシュボードを作成できるようになります。

ウェブに関する指標コネクタ レポートのスクリーンショット

ウェブに関する指標コネクタ レポートのスクリーンショット

ここで説明したすべての手順の概要を視覚的に確認するには、Google I/O 2021 の講演をご覧ください。

測定

Google アナリティクスでは、これまでもカスタム指標を使ってパフォーマンスを測定してきましたが、Google アナリティクス 4(GA4)には、デベロッパーの皆様が特に注目すべき新機能がいくつかあります。

Google アナリティクスのウェブ インターフェースには強力な分析ツールが備わっていますが、なじみのあるクエリ言語を使用して、未加工のイベントデータにアクセスする威力と柔軟性に勝つことは困難です。

Google アナリティクス 4 と BigQuery を使用してウェブに関する主な指標の測定を始めるには、次の 3 つのことを行う必要があります。

  1. Google アナリティクス 4 プロパティBigQuery プロジェクトを作成します。
  2. Google アナリティクスのプロパティ設定で BigQuery Export を有効にすると、受信したすべてのデータが BigQuery プロジェクトのテーブルに自動的に入力されます。
  3. web-vitals JavaScript ライブラリをサイトに追加すると、ウェブに関する主な指標の指標を測定して、データを Google アナリティクス 4 に送信できるようになります。

分析

すべての設定が完了すると、BigQuery インターフェースにイベントデータが入力され、次のようにデータをクエリできるようになります。

SELECT * FROM `my_project_id.analytics_XXXXX.events_*`
WHERE event_name IN ('LCP', 'FID', 'CLS')

このクエリの結果のプレビューは次のとおりです。

BigQuery の Web Vitals イベントデータ

ウェブに関する指標データにクエリを実行する

Web Vitals イベントデータのクエリを開始する前に、データの集計方法を理解しておくことが重要です。

最も重要なことは、場合によっては、同じページで同じ指標に対して複数のイベントを受信する可能性があることです。これは、指標値が変更され、更新された値が報告された場合に発生することがあります(CLS でよく発生します)。

ウェブに関する指標イベントの場合、最後に送信された値が常に最も正確な値になるため、分析を行う前に、それらの値のみでフィルタリングすることが重要です。Google アナリティクス 4 にデータを送信するために web-vitals JavaScript ライブラリが提供するコード スニペットには、指標ごとに一意の ID が送信されるため、次のクエリを使用すると、各指標 ID について最後に受信した値のみに結果を限定できます。

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'FID', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)

この投稿で参照している他のすべてのクエリは、このサブクエリで始まります。

以降のセクションでは、実行する可能性がある一般的なウェブに関する指標のクエリの例を示します。

クエリの例

サイト全体で 75 パーセンタイル(p75)での LCP、FID、CLS

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'FID', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  metric_name,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS p75,
  COUNT(1) as count
FROM (
  SELECT
    metric_name,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
  FROM web_vitals_events
)
GROUP BY 1

すべての個々の LCP 値を降順

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'FID', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
FROM web_vitals_events
WHERE metric_name = 'LCP'
ORDER BY metric_value DESC
# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'FID', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  page_path,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS LCP,
  COUNT(1) as count
FROM (
  SELECT
    REGEXP_SUBSTR((SELECT value.string_value FROM UNNEST(event_params) WHERE key = "page_location"), r'\.com(\/[^?]*)') AS page_path,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
  FROM web_vitals_events
  WHERE metric_name = 'LCP'
)
GROUP BY 1
ORDER BY count DESC
LIMIT 10

CLS が最も低い上位 10 ページ(p75)

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'FID', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  page_path,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS CLS,
  COUNT(1) as count
FROM (
  SELECT
    REGEXP_SUBSTR((SELECT value.string_value FROM UNNEST(event_params) WHERE key = "page_location"), r'\.com(\/[^?]*)') AS page_path,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
  FROM web_vitals_events
  WHERE metric_name = 'CLS'
)
GROUP BY 1
HAVING count > 50 # Limit to relatively popular pages
ORDER BY CLS DESC
LIMIT 10

デバッグ

上記のクエリは、Web Vitals の指標データをクエリする方法を示しており、現在のパフォーマンスと時間の経過に伴う傾向を把握するうえで役立ちます。しかし、パフォーマンスが予想より低いものの、原因がわからない場合、どうすればよいでしょうか。

スコアがかを知ることは、行動を起こして問題を解決できない場合には役に立ちません。

フィールドでのデバッグ パフォーマンスでは、分析データとともに追加のデバッグ情報を送信する方法について説明します。その投稿で説明されている手順に沿って操作すると、BigQuery にデバッグ情報も表示されるはずです。

次のクエリは、debug_target イベント パラメータを使用してパフォーマンスの問題の根本原因を特定する方法を示しています。

クエリの例

CLS に影響する主な要素

debug_target は、ページ上の指標の値に最も関連する要素に対応する CSS セレクタ文字列です。

CLS の場合、debug_target は、CLS 値に影響を与えた最大レイアウト シフトの最大要素を表します。シフトされた要素がない場合、debug_target 値は null になります。

次のクエリは、CLS の最も低いものから最も良いものの順に、75 パーセンタイルで debug_target でグループ化されたページを一覧表示します。

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'FID', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  page_path,
  debug_target,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS CLS,
  COUNT(1) as count
FROM (
  SELECT
    REGEXP_SUBSTR((SELECT value.string_value FROM UNNEST(event_params) WHERE key = "page_location"), r'\.com(\/[^?]*)') AS page_path,
    (SELECT value.string_value FROM UNNEST(event_params) WHERE key = "debug_target") as debug_target,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
    *
  FROM web_vitals_events
  WHERE metric_name = 'CLS'
)
GROUP BY 1, 2
HAVING count > 50 # Limit to relatively popular pages
ORDER BY CLS DESC

CLS に影響する上位要素のクエリ結果

ページ上のどの要素が移動しているかを把握することで、問題の根本原因の特定と修正が容易になります。

ここで報告される要素は、ページをローカルでデバッグしているときにシフトしている要素と同じではない場合があるので、最初にこのデータをキャプチャすることが非常に重要になります。問題だと気付いていないものを修正するのは とても難しいことです

他の指標をデバッグする

上記のクエリは CLS 指標の結果を表示しますが、まったく同じ手法を使用して LCP と FID のデバッグ ターゲットに関するレポートを作成することもできます。where 句をデバッグする関連指標に置き換えるだけです。

WHERE metric_name = 'CLS'
WHERE metric_name = 'LCP'

ここでも、Core Web Vitals の各指標のデバッグ情報を収集して送信する方法については、実際のパフォーマンスをデバッグするをご覧ください。

可視化

クエリ結果だけを見るだけでは、分析情報を得るのは簡単ではありません。たとえば、次のクエリは、データセット内の LCP の日別 75 パーセンタイル値を一覧表示します。

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'FID', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  event_date,
  metric_name,
  APPROX_QUANTILES(ROUND(metric_value, 2), 100)[OFFSET(75)] AS p75
FROM
  (
    SELECT
      event_date,
      metric_name,
      ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value'), 3) AS metric_value
    FROM web_vitals_events
    WHERE
      metric_name = 'LCP'
  )
GROUP BY
  1, 2
ORDER BY event_date

これらのクエリ結果から、データを見るだけで傾向や外れ値を特定することは困難です。

1 日の指標値のクエリ結果

そのような場合は、データを可視化することで、より迅速に分析情報を導き出すことができます。

Looker Studio でクエリ結果を可視化する

BigQuery では、データポータルを使用してクエリ結果をすばやく可視化できます。Looker Studio は、無料で使用できるデータの可視化とダッシュボード作成のツールです。クエリ結果を可視化するには、BigQuery UI でクエリを実行した後、[データを探索] ボタンをクリックして [Looker Studio で調べる] を選択します。

BigQuery の [Looker Studio で調べる] オプション

これにより、BigQuery から Looker Studio への直接リンクが Explore ビューに作成されます。このビューでは、可視化するフィールドの選択、グラフの種類の選択、フィルタの設定、アドホック グラフの作成を簡単にビジュアル分析できます。上記のクエリ結果から次の折れ線グラフを作成すると、時間の経過に伴う LCP 値の傾向を確認できます。

Looker Studio の日別 LCP 値の折れ線グラフ

BigQuery と Looker Studio を直接リンクすると、任意のクエリから簡単なグラフを作成し、ビジュアル分析を行うことができます。ただし、さらに分析を行う場合は、インタラクティブなダッシュボードで複数のグラフを表示して、より包括的なビューを取得したり、データをドリルダウンしたりできます。便利なダッシュボードがあると、指標を分析するたびに、手動でクエリを作成してグラフを生成する必要がなくなります。

ネイティブ BigQuery コネクタを使用して、Looker Studio でダッシュボードを作成できます。そのためには、datastudio.google.com に移動して新しいデータソースを作成し、BigQuery コネクタを選択して、使用するデータセットを選択します。

Looker Studio で BigQuery ネイティブ コネクタを使用する

ウェブに関する指標データを実体化する

上記のように、ウェブに関する指標のイベントデータのダッシュボードを作成する場合、Google アナリティクス 4 のエクスポート データセットを直接使用するのは効率的ではありません。GA4 データの構造とウェブに関する指標の指標に必要な前処理により、クエリの一部が複数回実行されることになります。これにより、ダッシュボードのパフォーマンスと BigQuery の費用という 2 つの問題が発生します。

BigQuery サンドボックス モードは無料でご利用いただけます。BigQuery の無料枠では、処理されるクエリデータが毎月 1 TB まで無料です。この投稿で説明する分析方法では、非常に大規模なデータセットを使用している場合や、データセットに定期的に大量のクエリを実行している場合を除き、毎月この無料制限内に収まるはずです。ただし、トラフィックの多いウェブサイトで、高速のインタラクティブなダッシュボードを使用してさまざまな指標を定期的にモニタリングする場合は、パーティショニング、クラスタリング、キャッシュなどの BigQuery の効率性機能を利用しながら、ウェブに関する指標データの前処理と実体化を行うことをおすすめします。

次のスクリプトは、BigQuery データ(ソーステーブル)を前処理し、マテリアライズド テーブル(ターゲット テーブル)を作成します。このクエリを独自のデータセットに使用する場合は、ソーステーブルの期間を定義して、処理されるデータ量を減らすこともできます。

# Materialize Web Vitals metrics from GA4 event export data

# Replace target table name
CREATE OR REPLACE TABLE bigquery_project_id.ga4_demo_dev.web_vitals_summary
  PARTITION BY DATE(event_timestamp)
  CLUSTER BY metric_name
AS
SELECT
  ga_session_id,
  IF(
    EXISTS(SELECT 1 FROM UNNEST(events) AS e WHERE e.event_name = 'first_visit'),
    'New user',
    'Returning user') AS user_type,
  IF(
    (SELECT MAX(session_engaged) FROM UNNEST(events)) > 0, 'Engaged', 'Not engaged')
    AS session_engagement,
  evt.* EXCEPT (session_engaged, event_name),
  event_name AS metric_name,
  FORMAT_TIMESTAMP('%Y%m%d', event_timestamp) AS event_date
FROM
  (
    SELECT
      ga_session_id,
      ARRAY_AGG(custom_event) AS events
    FROM
      (
        SELECT
          ga_session_id,
          STRUCT(
            country,
            device_category,
            device_os,
            traffic_medium,
            traffic_name,
            traffic_source,
            page_path,
            debug_target,
            event_timestamp,
            event_name,
            metric_id,
            IF(event_name = 'LCP', metric_value / 1000, metric_value) AS metric_value,
            user_pseudo_id,
            session_engaged,
            session_revenue) AS custom_event
        FROM
          (
            SELECT
              (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')
                AS ga_session_id,
              (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
                AS metric_id,
              ANY_VALUE(device.category) AS device_category,
              ANY_VALUE(device.operating_system) AS device_os,
              ANY_VALUE(traffic_source.medium) AS traffic_medium,
              ANY_VALUE(traffic_source.name) AS traffic_name,
              ANY_VALUE(traffic_source.source) AS traffic_source,
              ANY_VALUE(
                REGEXP_SUBSTR(
                  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location'),
                  r'^[^?]+')) AS page_path,
              ANY_VALUE(
                (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'debug_target'))
                AS debug_target,
              ANY_VALUE(user_pseudo_id) AS user_pseudo_id,
              ANY_VALUE(geo.country) AS country,
              ANY_VALUE(event_name) AS event_name,
              SUM(ecommerce.purchase_revenue) AS session_revenue,
              MAX(
                (
                  SELECT
                    COALESCE(
                      value.double_value, value.int_value, CAST(value.string_value AS NUMERIC))
                  FROM UNNEST(event_params)
                  WHERE key = 'session_engaged'
                )) AS session_engaged,
              TIMESTAMP_MICROS(MAX(event_timestamp)) AS event_timestamp,
              MAX(
                (
                  SELECT COALESCE(value.double_value, value.int_value)
                  FROM UNNEST(event_params)
                  WHERE key = 'metric_value'
                )) AS metric_value,
            FROM
              # Replace source table name
              `bigquery_project_id.analytics_XXXXX.events_*`
            WHERE
              event_name IN ('LCP', 'FID', 'CLS', 'first_visit', 'purchase')
            GROUP BY
              1, 2
          )
      )
    WHERE
      ga_session_id IS NOT NULL
    GROUP BY ga_session_id
  )
CROSS JOIN UNNEST(events) AS evt
WHERE evt.event_name NOT IN ('first_visit', 'purchase');

この実体化されたデータセットにはいくつかの利点があります。

  • データ構造がフラット化され、クエリが容易になります。
  • 元の GA4 データセットのウェブに関する指標イベントのみが保持されます。
  • セッション ID、ユーザータイプ(新規とリピーター)、セッション エンゲージメント情報は、列で直接確認できます。
  • テーブルは日付でpartitionedされ、指標名でクラスタ化されます。これにより、通常、各クエリで処理されるデータの量が削減されます。
  • このテーブルをクエリするためにワイルドカードを使用する必要はないため、クエリ結果は最大 24 時間キャッシュに保存されます。これにより、同じクエリを繰り返すコストが削減されます。
  • BigQuery BI エンジンを使用している場合は、このテーブルで最適化された SQL 関数と演算子を実行できます。

このマテリアライズド テーブルは、BigQuery UI から直接クエリできます。また、BigQuery コネクタを使用して Looker Studio で使用することもできます。

ウェブに関する指標コネクタの使用

ダッシュボードをゼロから作成するには時間がかかるため、テンプレート ダッシュボードを作成するパッケージ ソリューションを開発しました。まず、上記のクエリを使用してウェブに関する指標テーブルが実体化されていることを確認します。次に、こちらのリンク(goo.gle/web-vitals-connector)を使用して、Looker Studio 用のウェブに関する指標コネクタにアクセスします。

1 回限りの承認を提供すると、次の構成画面が表示されます。

Web Vitals コネクタの承認画面

実体化された BigQuery テーブル ID(ターゲット テーブル)と BigQuery 課金プロジェクト ID を指定します。[接続] をクリックすると、テンプレート化された新しいダッシュボードが作成され、データがそのダッシュボードに関連付けられます。ダッシュボードは必要に応じて編集、変更、共有できます。ダッシュボードを 1 回作成した後は、異なるデータセットから複数のダッシュボードを作成する場合を除き、コネクタのリンクに再度アクセスする必要はありません。

ダッシュボードを操作すると、[Summary] タブで、Web Vitals の指標の日々の傾向と、ユーザー、セッションなど、ウェブサイトの使用状況に関するいくつかの情報を確認できます。

[User Analysis] タブでは、指標を選択すると、指標のパーセンタイルと、使用状況やビジネス指標ごとのユーザー数の内訳を確認できます。

[ページパス分析] タブは、ウェブサイト上の問題のある領域を特定するのに役立ちます。ここで指標を選択すると、概要が表示されます。y 軸にパーセンタイル値、x 軸にレコード数が含まれた、すべてのページパスの散布図も表示されます。散布図は、指標の値が想定より低いページを特定するのに役立ちます。[ページパス] テーブルの散布図を使用してページを選択したら、[デバッグ ターゲット] テーブルを表示して、問題領域をさらにドリルダウンできます。

[収益分析] タブは、ビジネスとパフォーマンスの指標を同じ場所でモニタリングする方法の一例です。このセクションには、ユーザーが購入したすべてのセッションがプロットされます。特定のセッションにおける 収益とユーザーエクスペリエンスを比較できます

高度な使用方法

データセットに慣れてきたら、ダッシュボードを編集し、独自のグラフを追加して、より豊富でターゲットを絞った分析を行うことができます。ダッシュボードの利便性を高めるには、次の操作を行います。

  • BigQuery でスケジュールされたクエリを設定して、更新されたデータを取得します。上で実行した実体化クエリは、その時点でのデータのスナップショットのみを取得します。新しいデータでダッシュボードを更新し続けるには、毎日実行されるスケジュールされたクエリを実行し、新しいデータを含むマテリアライズド テーブルを追加します。
  • 自社データ(CRM など)を結合してビジネス インサイトを獲得。マテリアライズド テーブルでは、user_id を別の列として追加できます。これにより自社データを結合できますファースト パーティ データがまだ BigQuery にない場合は、データを読み込むか、フェデレーション データソースを使用します。
  • Google アナリティクスに送信するデータのパラメータとしてサイトまたはアプリのバージョンを報告し、マテリアライズド テーブルの列として追加します。その後、そのバージョン データをディメンションとしてグラフに追加することで、バージョンの変更がパフォーマンスに与える影響を簡単に確認できます。
  • 直接クエリまたはダッシュボードを通じてデータセットの使用量が非常に多くなることが予想される場合は、有料バージョンの BigQuery BI Engine をお試しください。

まとめ

この投稿では、Google アナリティクス 4 と BigQuery を使用し、現場で収集された実際のユーザーデータを使用してパフォーマンスを測定し、デバッグする方法の基本について説明しました。また、Looker Studio と Web Vitals コネクタを使用して自動化されたレポートとダッシュボードを構築し、データをできるだけ簡単に可視化する方法について説明しました。

この投稿の重要なポイント:

  • 実際のユーザーデータを使用してパフォーマンスを測定することは、サイトを理解、デバッグ、最適化するために不可欠です。
  • パフォーマンス指標とビジネス指標が同じシステムにある場合、より詳細な分析情報を取得できます。これを可能にしているのが Google アナリティクスと BigQuery です
  • Google アナリティクスの元データを BigQuery にエクスポートすると、使い慣れたクエリ言語を使用して、詳細なカスタム分析を行えます。
  • Google には Looker Studio などのさまざまな API と可視化ツールがあり、希望する方法で自由にレポートを作成できます。