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

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

Google は、Search ConsolePageSpeed Insights(PSI)、Chrome ユーザー エクスペリエンス レポート(CrUX)などのさまざまなツールを提供しています。これらのツールを使用すると、デベロッパーは、現場の実際のユーザーに対して、サイトの Core Web Vitals 指標のパフォーマンスを確認できます。

これらのツールは、サイトの実際のユーザー パフォーマンスの概要を把握でき、使用を開始するためにセットアップがまったく必要ないという点で優れています。

ただし、これらのツールのみを使用してサイトのパフォーマンスを測定することはおすすめしません。その理由は次のとおりです。

  • CrUX ベースのツールでは、データが月単位または過去 28 日間のいずれかでレポートされます。そのため、変更を加えた後、結果を確認できるようになるまでに長い時間がかかります。
  • CrUX ベースのツールでは、国、接続タイプ、デバイス カテゴリ(パソコンまたはモバイル)など、限られた数のディメンションでのみセグメント化できます。ビジネス固有のディメンション(エンゲージメントの高いユーザー、特定のテストのグループのユーザーなど)でデータをスライスすることはできません。
  • CrUX ベースのツールでは、パフォーマンスの内容はわかりますが、理由はわかりません。アナリティクス ツールを使用すると、問題の追跡とデバッグに役立つ追加データを送信できます。

こうした理由から、すべてのサイト所有者には、既存の分析ツールを使用してウェブに関する主な指標をモニタリングすることをおすすめします。この記事では、Google が提供する無料ツールを使用して、この作業を行う方法について説明します。

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

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

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

上記のすべての手順を視覚的に確認するには、Google I/O '21 での Google の講演をご覧ください。

測定

パフォーマンスの測定は、Google アナリティクスで常にカスタム指標を使用して行えますが、Google アナリティクス 4(GA4)には、特にデベロッパー向けの新しい機能がいくつかあります。

Google アナリティクスのウェブ インターフェースには強力な分析ツールが用意されていますが、すでにご存じのクエリ言語を使用して未加工のイベントデータにアクセスする柔軟性と強力さにはかないません。

Google アナリティクス 4 と BigQuery を使用してウェブに関する主な指標の測定を開始するには、次の 3 つの手順が必要です。

  1. Google アナリティクス 4 プロパティBigQuery プロジェクトを作成します。
  2. Google アナリティクス プロパティの設定で BigQuery Export を有効にすると、受信したすべてのデータが BigQuery プロジェクト テーブルに自動的に入力されます。
  3. サイトに web-vitals JavaScript ライブラリを追加して、Core Web Vitals 指標を測定し、アトリビューション データを含むデータを Google アナリティクス 4 に送信します。

分析

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

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

クエリの結果のプレビューを次に示します。

BigQuery のウェブバイタル イベントデータ

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

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

最も重要なことは、同じページで同じ指標について複数のイベントが受信される可能性があることです。これは、指標値が変更され、更新された値がレポートされた場合に発生することがあります(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', 'INP', '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
)

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

クエリの例

以降のセクションでは、実行する必要がある一般的なウェブバイタル クエリの例をいくつか示します。

サイト全体の LCP、INP、CLS の 75 パーセンタイル(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', 'INP', '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', 'INP', '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', 'INP', '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(p75)が最も低い上位 10 ページ

# 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', 'INP', '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

デバッグ

上記のクエリは、現在のパフォーマンスと時間の経過に伴う傾向を把握するのに役立つ、Core 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', 'INP', '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 と INP のデバッグ ターゲットをレポートできます。where 句を関連する指標に置き換えてデバッグするだけです。

WHERE metric_name = 'INP'
WHERE metric_name = 'LCP'

各ウェブに関する主な指標のデバッグ情報を収集して送信する方法については、フィールドでパフォーマンスをデバッグするをご覧ください。

可視化

クエリ結果のみを調べて分析情報を得るのは難しい場合があります。たとえば、次のクエリは、データセット内の 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', 'INP', '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 への直接リンクが作成されます。このビューでは、可視化するフィールドの選択、グラフの種類の選択、フィルタの設定、アドホック グラフの作成を行って、視覚的な分析を迅速に行うことができます。前述のクエリ結果から次の折れ線グラフを作成して、LCP 値の推移を確認できます。

Looker Studio による毎日の LCP 値の折れ線グラフ

こうした BigQuery と Looker Studio の直接リンクにより、任意のクエリから簡単なグラフを作成し、視覚的な分析を行うことができます。ただし、さらに分析する場合は、インタラクティブなダッシュボードで複数のグラフを確認して、全体像を把握するか、データを詳しく確認できるようにすることをおすすめします。便利なダッシュボードがあれば、指標を分析するたびにクエリを記述してグラフを手動で生成する必要がなくなります。

Looker Studio では、ネイティブ BigQuery コネクタを使用してダッシュボードを作成できます。そのためには、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', 'INP', '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、ユーザータイプ(新規かリピーターか)、セッション エンゲージメント情報を、列で直接利用できます。
  • テーブルが日付で分割され、指標名でクラスタ化されます。これにより、通常は各クエリで処理されるデータ量が削減されます。
  • このテーブルをクエリするためにワイルドカードを使用する必要はないため、クエリ結果を最大 24 時間キャッシュに保存できます。これにより、同じクエリを繰り返すことによる費用を削減できます。
  • BigQuery BI Engine を使用する場合は、最適化された SQL 関数と演算子をこのテーブルで実行できます。

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

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

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

1 回限りの承認を行うと、次の設定画面が表示されます。

ウェブに関する指標コネクタの承認画面

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

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

[ユーザー分析] タブでは、指標を選択し、ユーザー数だけでなく、種々の使用状況やビジネス指標別に指標のパーセンタイルの内訳を確認できます。

[ページ経路の分析] タブでは、ウェブサイトの問題のある部分を特定できます。ここで指標を選択すると、概要が表示されます。すべてのページパスの散布図も表示されます(Y 軸はパーセンタイル値、X 軸はレコード数)。散布図では、指標の値が想定よりも低いページを特定できます。ページパス テーブルの散布図を使用してページを選択したら、デバッグ ターゲット テーブルを表示して、問題のある部分をさらに詳しく確認できます。

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

高度な使用方法

データセットに慣れてきたら、ダッシュボードを編集して独自のグラフを追加し、より詳細で的確な分析を行うことができます。ダッシュボードをより有用にするには、次の手順を行います。

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

概要

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

この投稿の重要なポイントは次のとおりです。

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