Отслеживание эффективности и устранение неполадок с помощью Google Аналитики 4 и BigQuery

Узнайте, как отправлять данные Web Vitals в ресурсы Google Analytics 4 и экспортировать данные для анализа в BigQuery и Looker Studio.

Google предоставляет ряд инструментов — Search Console , PageSpeed ​​Insights (PSI) и Chrome User Experience Report (CrUX), — которые позволяют разработчикам видеть, как их сайты работают по сравнению с показателями Core Web Vitals для их реальных пользователей в этой области .

Эти инструменты хороши тем, что дают вам общее представление о реальной производительности вашего сайта и не требуют абсолютно никакой настройки для начала использования.

Однако есть несколько важных причин, по которым вы не хотите полагаться только на эти инструменты для измерения производительности вашего сайта:

  • Инструменты на основе CruX предоставляют данные либо за месяц, либо за предыдущие 28-дневные периоды. Это означает, что вам придется долго ждать после внесения каких-либо изменений, прежде чем вы сможете увидеть результаты.
  • Инструменты на основе CrUX можно сегментировать только по ограниченному числу параметров, таких как страна, тип подключения и категория устройства (настольное или мобильное). Вы не можете разделить данные по параметрам, специфичным для вашего бизнеса (например, вовлеченные пользователи, пользователи в определенной экспериментальной группе и т. д.).
  • Инструменты на основе CrUX могут сказать вам, какова ваша производительность, но они не могут сказать вам, почему . С помощью инструментов аналитики вы можете отправлять дополнительные данные, которые помогут отслеживать и устранять проблемы.

По этим причинам мы рекомендуем всем владельцам сайтов отслеживать показатели Core Web Vitals, используя существующие инструменты аналитики. В этом посте объясняется, как для этого можно использовать бесплатные инструменты, предлагаемые Google.

После того, как вы все настроите, вы сможете создавать такие информационные панели:

Скриншот отчета Web Vitals Connector

Скриншот отчета Web Vitals Connector

Если вам нужен визуальный обзор всех шагов, описанных здесь, ознакомьтесь с нашим докладом на Google I/O '21 :

Мера

Измерение эффективности всегда было возможно с помощью Google Analytics с использованием специальных показателей , но в Google Analytics 4 (GA4) есть несколько новых функций, которые особенно должны интересовать разработчиков.

Хотя веб-интерфейс Google Analytics имеет мощные инструменты анализа, трудно превзойти мощь и гибкость доступа к необработанным данным о событиях с использованием языка запросов, который вы, вероятно, уже знаете.

Чтобы начать измерять основные веб-показатели с помощью Google Analytics 4 и BigQuery, вам нужно сделать три вещи:

  1. Создайте ресурс Google Analytics 4 и проект BigQuery .
  2. Включите экспорт BigQuery в конфигурации ресурса Google Analytics, чтобы все полученные данные автоматически заполнялись в таблицах вашего проекта BigQuery.
  3. Добавьте на свой сайт библиотеку JavaScript Web-Vitals , чтобы иметь возможность измерять основные показатели Web-Vitals и отправлять данные в Google Analytics 4 , включая данные атрибуции .

Анализировать

После того, как вы все настроите, вы должны увидеть данные о событиях, заполняющиеся в интерфейсе BigQuery, и вы сможете запрашивать данные следующим образом:

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

Вот предварительный просмотр результатов этого запроса:

Данные о событиях Web Vitals в BigQuery

Запрос данных Web Vitals

Прежде чем вы начнете запрашивать данные о событиях Web Vitals, важно понять, как данные агрегируются.

Самое важное, что нужно понимать, это то, что в некоторых случаях для одной и той же метрики на одной странице может быть получено несколько событий . Это может произойти, если значение метрики изменится и будет сообщено обновленное значение (обычное явление для CLS).

Для событий Web Vitals последнее отправленное значение всегда является наиболее точным, поэтому перед выполнением любого анализа важно отфильтровать только эти значения. Фрагмент кода, предоставленный библиотекой JavaScript web-vitals для отправки данных в Google Analytics 4, включает отправку уникального идентификатора для каждой метрики, поэтому вы можете использовать следующий запрос, чтобы ограничить ваши результаты только последним полученным значением для каждого идентификатора метрики:

# 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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
)

Обратите внимание, что все остальные запросы, упомянутые в этом посте, начнутся с этого подзапроса.

Примеры запросов

В следующих нескольких разделах показано несколько примеров распространенных запросов Web Vitals, которые вы, возможно, захотите выполнить.

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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

Топ-10 страниц с худшим CLS (стр. 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

Отлаживать

Предыдущие запросы показывают, как запрашивать данные показателей 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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'

Опять же, вы можете обратиться к разделу «Производительность отладки» для получения инструкций о том, как собирать и отправлять отладочную информацию для каждой из метрик Core Web Vitals.

Визуализируйте

Получить ценную информацию, просто взглянув только на результаты запроса, может оказаться непросто. Например, следующий запрос перечисляет ежедневные значения 75-го процентиля для 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

По результатам этих запросов трудно выявить тенденции или выбросы, просто просматривая данные.

Результаты запроса значений ежедневных показателей

В таких случаях визуализация данных может помочь вам быстрее получить ценную информацию.

Визуализация результатов запроса в Looker Studio

BigQuery предоставляет быстрый способ визуализировать любые результаты запроса через Студию данных. Looker Studio — это бесплатный инструмент для визуализации данных и создания информационных панелей. Чтобы визуализировать результаты запроса, после выполнения запроса в пользовательском интерфейсе BigQuery нажмите кнопку «Исследовать данные» и выберите «Исследовать с помощью Looker Studio» .

Исследуйте с помощью функции Looker Studio в BigQuery

Это создаст прямую ссылку из BigQuery на Looker Studio в представлении исследования. В этом представлении вы можете выбрать поля, которые хотите визуализировать, выбрать типы диаграмм, настроить фильтры и создать специальные диаграммы для быстрого визуального анализа. На основе результатов предыдущего запроса вы можете создать следующую линейную диаграмму, чтобы увидеть тенденцию значений LCP с течением времени:

Линейный график ежедневных значений LCP в Looker Studio

Благодаря прямой связи между BigQuery и Looker Studio вы можете создавать быстрые диаграммы на основе любых ваших запросов и выполнять визуальный анализ. Однако если вы хотите провести дополнительный анализ, возможно, вам захочется просмотреть несколько диаграмм на интерактивной информационной панели, чтобы получить более целостное представление или иметь возможность детализировать данные. Наличие удобной информационной панели означает, что вам не придется писать запросы и создавать диаграммы вручную каждый раз, когда вы хотите проанализировать свои показатели.

Вы можете создать дашборд в Looker Studio, используя собственный коннектор BigQuery . Для этого перейдите на datastudio.google.com , создайте новый источник данных, выберите коннектор BigQuery и выберите набор данных, с которым вы хотите работать:

Использование собственного коннектора BigQuery в Looker Studio

Материализация данных Web Vitals

При создании информационных панелей с данными событий Web Vitals, как описано ранее, напрямую использовать набор экспортированных данных Google Analytics 4 неэффективно. Из-за структуры данных GA4 и предварительной обработки, необходимой для показателей Web Vitals, части вашего запроса будут выполняться несколько раз. Это создает две проблемы: производительность информационной панели и затраты на BigQuery.

Вы можете использовать режим песочницы BigQuery бесплатно. Благодаря бесплатному уровню использования BigQuery первый 1 ТБ данных запросов, обрабатываемых в месяц, предоставляется бесплатно. Для методов анализа, обсуждаемых в этом посте, если вы не используете значительно большой набор данных или регулярно запрашиваете набор данных, вы должны иметь возможность оставаться в пределах этого бесплатного лимита каждый месяц. Но если у вас веб-сайт с высокой посещаемостью и вы хотите регулярно отслеживать различные показатели с помощью быстрой интерактивной информационной панели, мы предлагаем выполнить предварительную обработку и материализацию данных о веб-показателях, используя при этом функции повышения эффективности 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');

Этот материализованный набор данных имеет несколько преимуществ:

  • Структура данных более плоская, и ее легче запрашивать.
  • Он сохраняет только события Web Vitals из исходного набора данных GA4.
  • Идентификатор сеанса, тип пользователя (новый или вернувшийся) и информация об участии в сеансе доступны непосредственно в столбцах.
  • Таблица секционирована по дате и кластеризована по имени метрики. Обычно это уменьшает объем данных, обрабатываемых для каждого запроса.
  • Поскольку для запроса к этой таблице не нужно использовать подстановочные знаки, результаты запроса могут кэшироваться на срок до 24 часов. Это снижает затраты на повторение одного и того же запроса.
  • Если вы используете механизм BigQuery BI, вы можете запускать оптимизированные функции и операторы SQL в этой таблице.

Вы можете напрямую запросить эту материализованную таблицу из пользовательского интерфейса BigQuery или использовать ее в Looker Studio с помощью коннектора BigQuery.

Используйте коннектор Web Vitals

Поскольку создание дашборда с нуля требует много времени, мы разработали комплексное решение, которое создаст для вас шаблон дашборда. Сначала убедитесь, что вы материализовали таблицу Web Vitals с помощью предыдущего запроса. Затем войдите в коннектор Web Vitals для Looker Studio по этой ссылке: goo.gle/web-vitals-connector.

После предоставления однократной авторизации вы должны увидеть следующий экран конфигурации:

Экран авторизации Web Vitals Connector

Укажите материализованный идентификатор таблицы BigQuery (т. е. целевую таблицу) и идентификатор вашего платежного проекта BigQuery. После нажатия кнопки «Подключиться» Looker Studio создаст новую шаблонную панель мониторинга и свяжет с ней ваши данные. Вы можете редактировать, изменять и делиться панелью мониторинга по своему усмотрению. Если вы создаете панель мониторинга один раз, вам не нужно повторно посещать ссылку соединителя, если только вы не хотите создать несколько панелей мониторинга из разных наборов данных.

Перемещаясь по информационной панели, вы можете видеть ежедневные тенденции показателей Web Vitals и некоторую информацию об использовании вашего веб-сайта, такую ​​​​как пользователи и сеансы, на вкладке «Сводка» .

На вкладке «Анализ пользователей» вы можете выбрать метрику, а затем получить разбивку процентиля метрик, а также количество пользователей по различным показателям использования и бизнеса.

Вкладка «Анализ пути страницы» поможет вам выявить проблемные области на вашем веб-сайте. Здесь вы можете выбрать показатель, чтобы просмотреть обзор. Но вы также видите карту разброса всех путей к страницам со значением процентиля по оси Y и количеством записей по оси X. Карта разброса может помочь выявить страницы, значения показателей которых ниже ожидаемых. Выбрав страницы с помощью точечной диаграммы таблицы путей к страницам , вы можете дополнительно детализировать проблемную область, просмотрев таблицу «Цель отладки» .

Вкладка «Анализ доходов» — это пример того, как вы можете отслеживать показатели своего бизнеса и производительности в одном месте. В этом разделе отображаются все сеансы, в которых пользователь совершил покупку. Вы можете сравнить полученный доход с пользовательским опытом во время конкретного сеанса.

Расширенное использование

По мере того, как вы ближе познакомитесь с набором данных, вы сможете редактировать панель мониторинга и добавлять свои собственные диаграммы для более детального и целенаправленного анализа. Чтобы сделать информационную панель более полезной, вы можете предпринять следующие шаги:

  • Настройте запланированный запрос в BigQuery для получения обновленных данных. Запрос материализации, который мы выполняли ранее, делает только снимок ваших данных на данный момент. Если вы хотите, чтобы ваша панель мониторинга обновлялась новыми данными, вы можете запустить запланированный запрос, который будет выполняться каждый день, и добавить в материализованную таблицу новые данные.
  • Присоединяйтесь к собственным данным (например, CRM) для получения бизнес-информации. В материализованной таблице можно добавить user_id отдельным столбцом. Это позволит вам присоединиться к своим основным данным. Если ваши собственные данные еще не находятся в BigQuery, вы можете либо загрузить данные , либо использовать интегрированный источник данных .
  • Укажите версию своего сайта или приложения в качестве параметра данных, которые вы отправляете в Google Analytics, и добавьте ее в качестве столбца в материализованной таблице. Затем вы можете добавить эти данные о версии в качестве измерения в свои диаграммы, чтобы было легче увидеть, как изменения версий влияют на производительность.
  • Если вы ожидаете значительно интенсивного использования набора данных посредством прямого запроса или панели управления, вы можете попробовать использовать платную версию BigQuery BI Engine .

Краткое содержание

В этом посте рассказывается об основах использования Google Analytics 4 и BigQuery для измерения и отладки производительности на основе данных реальных пользователей, собранных в полевых условиях. Также объясняется, как создавать автоматизированные отчеты и информационные панели с помощью Looker Studio и Web Vitals Connector, чтобы максимально упростить визуализацию данных.

Некоторые ключевые выводы из этого поста:

  • Измерение производительности с использованием реальных пользовательских данных имеет решающее значение для понимания, отладки и оптимизации вашего сайта.
  • Вы можете получить более глубокое понимание, когда ваши показатели производительности и показатели вашего бизнеса находятся в одной системе. Google Analytics и BigQuery делают это возможным.
  • Экспорт необработанных данных Google Analytics в BigQuery дает вам неограниченные возможности для углубленного индивидуального анализа с использованием языка запросов, который вы, вероятно, уже знаете.
  • У Google есть ряд API и инструментов визуализации, таких как Looker Studio, которые дают вам свободу создавать отчеты именно так, как вы хотите.
,

Узнайте, как отправлять данные Web Vitals в ресурсы Google Analytics 4 и экспортировать данные для анализа в BigQuery и Looker Studio.

Google предоставляет ряд инструментов — Search Console , PageSpeed ​​Insights (PSI) и Chrome User Experience Report (CrUX), — которые позволяют разработчикам видеть, как их сайты работают по сравнению с показателями Core Web Vitals для реальных пользователей в этой области .

Эти инструменты хороши тем, что дают вам общее представление о реальной производительности вашего сайта и не требуют абсолютно никакой настройки для начала использования.

Однако есть несколько важных причин, по которым вы не хотите полагаться только на эти инструменты для измерения производительности вашего сайта:

  • Инструменты на основе CruX предоставляют данные либо за месяц, либо за предыдущие 28-дневные периоды. Это означает, что вам придется долго ждать после внесения каких-либо изменений, прежде чем вы сможете увидеть результаты.
  • Инструменты на основе CrUX можно сегментировать только по ограниченному числу параметров, таких как страна, тип подключения и категория устройства (настольное или мобильное). Вы не можете разделить данные по параметрам, специфичным для вашего бизнеса (например, вовлеченные пользователи, пользователи в определенной экспериментальной группе и т. д.).
  • Инструменты на основе CrUX могут сказать вам, какова ваша производительность, но они не могут сказать вам, почему . С помощью инструментов аналитики вы можете отправлять дополнительные данные, которые помогут отслеживать и устранять проблемы.

По этим причинам мы рекомендуем всем владельцам сайтов отслеживать показатели Core Web Vitals, используя существующие инструменты аналитики. В этом посте объясняется, как для этого можно использовать бесплатные инструменты, предлагаемые Google.

После того, как вы все настроите, вы сможете создавать такие информационные панели:

Скриншот отчета Web Vitals Connector

Скриншот отчета Web Vitals Connector

Если вам нужен визуальный обзор всех шагов, описанных здесь, ознакомьтесь с нашим докладом на Google I/O '21 :

Мера

Измерение эффективности всегда было возможно с помощью Google Analytics с использованием специальных показателей , но в Google Analytics 4 (GA4) есть несколько новых функций, которые особенно должны интересовать разработчиков.

Хотя веб-интерфейс Google Analytics имеет мощные инструменты анализа, трудно превзойти мощь и гибкость доступа к необработанным данным о событиях с использованием языка запросов, который вы, вероятно, уже знаете.

Чтобы начать измерять основные веб-показатели с помощью Google Analytics 4 и BigQuery, вам нужно сделать три вещи:

  1. Создайте ресурс Google Analytics 4 и проект BigQuery .
  2. Включите экспорт BigQuery в конфигурации ресурса Google Analytics, чтобы все полученные данные автоматически заполнялись в таблицах вашего проекта BigQuery.
  3. Добавьте на свой сайт библиотеку JavaScript Web-Vitals , чтобы можно было измерять основные показатели Web-Vitals и отправлять данные в Google Analytics 4 , включая данные атрибуции .

Анализировать

После того, как вы все настроите, вы должны увидеть данные о событиях, заполняющиеся в интерфейсе BigQuery, и вы сможете запрашивать данные следующим образом:

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

Вот предварительный просмотр результатов этого запроса:

Данные о событиях Web Vitals в BigQuery

Запрос данных Web Vitals

Прежде чем вы начнете запрашивать данные о событиях Web Vitals, важно понять, как данные агрегируются.

Самое важное, что нужно понимать, это то, что в некоторых случаях для одной и той же метрики на одной странице может быть получено несколько событий . Это может произойти, если значение метрики изменится и будет сообщено обновленное значение (обычное явление для CLS).

Для событий Web Vitals последнее отправленное значение всегда является наиболее точным, поэтому перед выполнением любого анализа важно отфильтровать только эти значения. Фрагмент кода, предоставленный библиотекой JavaScript web-vitals для отправки данных в Google Analytics 4, включает отправку уникального идентификатора для каждой метрики, поэтому вы можете использовать следующий запрос, чтобы ограничить ваши результаты только последним полученным значением для каждого идентификатора метрики:

# 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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
)

Обратите внимание, что все остальные запросы, упомянутые в этом посте, начнутся с этого подзапроса.

Примеры запросов

В следующих нескольких разделах показано несколько примеров распространенных запросов Web Vitals, которые вы, возможно, захотите выполнить.

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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

Топ-10 страниц с худшим CLS (стр. 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

Отлаживать

Предыдущие запросы показывают, как запрашивать данные показателей 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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'

Опять же, вы можете обратиться к разделу «Производительность отладки» для получения инструкций о том, как собирать и отправлять отладочную информацию для каждой метрики Core Web Vitals.

Визуализируйте

Получить ценную информацию, просто взглянув только на результаты запроса, может оказаться непросто. Например, следующий запрос перечисляет ежедневные значения 75-го процентиля для 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

По результатам этих запросов трудно выявить тенденции или выбросы, просто просматривая данные.

Результаты запроса значений ежедневных показателей

В таких случаях визуализация данных может помочь вам быстрее получить ценную информацию.

Визуализация результатов запроса в Looker Studio

BigQuery предоставляет быстрый способ визуализировать любые результаты запроса через Студию данных. Looker Studio — это бесплатный инструмент для визуализации данных и создания информационных панелей. Чтобы визуализировать результаты запроса, после выполнения запроса в пользовательском интерфейсе BigQuery нажмите кнопку «Исследовать данные» и выберите «Исследовать с помощью Looker Studio» .

Исследуйте с помощью функции Looker Studio в BigQuery

Это создаст прямую ссылку из BigQuery на Looker Studio в представлении исследования. В этом представлении вы можете выбрать поля, которые хотите визуализировать, выбрать типы диаграмм, настроить фильтры и создать специальные диаграммы для быстрого визуального анализа. На основе результатов предыдущего запроса вы можете создать следующую линейную диаграмму, чтобы увидеть тенденцию значений LCP с течением времени:

Линейный график ежедневных значений LCP в Looker Studio

Благодаря прямой связи между BigQuery и Looker Studio вы можете создавать быстрые диаграммы на основе любых ваших запросов и выполнять визуальный анализ. Однако если вы хотите провести дополнительный анализ, возможно, вам захочется просмотреть несколько диаграмм на интерактивной информационной панели, чтобы получить более целостное представление или иметь возможность детализировать данные. Наличие удобной информационной панели означает, что вам не придется писать запросы и создавать диаграммы вручную каждый раз, когда вы хотите проанализировать свои показатели.

Вы можете создать дашборд в Looker Studio, используя собственный коннектор BigQuery . Для этого перейдите на datastudio.google.com , создайте новый источник данных, выберите коннектор BigQuery и выберите набор данных, с которым вы хотите работать:

Использование собственного коннектора BigQuery в Looker Studio

Материализация данных Web Vitals

При создании информационных панелей с данными событий Web Vitals, как описано ранее, напрямую использовать набор экспортированных данных Google Analytics 4 неэффективно. Из-за структуры данных GA4 и предварительной обработки, необходимой для показателей Web Vitals, части вашего запроса будут выполняться несколько раз. Это создает две проблемы: производительность информационной панели и затраты на BigQuery.

Вы можете использовать режим песочницы BigQuery бесплатно. Благодаря бесплатному уровню использования BigQuery первый 1 ТБ данных запросов, обрабатываемых в месяц, предоставляется бесплатно. Для методов анализа, обсуждаемых в этом посте, если вы не используете значительно большой набор данных или регулярно запрашиваете набор данных, вы должны иметь возможность оставаться в пределах этого бесплатного лимита каждый месяц. Но если у вас веб-сайт с высокой посещаемостью и вы хотите регулярно отслеживать различные показатели с помощью быстрой интерактивной информационной панели, мы предлагаем выполнить предварительную обработку и материализацию данных веб-показателей, используя при этом функции повышения эффективности 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');

Этот материализованный набор данных имеет несколько преимуществ:

  • Структура данных более плоская, и ее легче запрашивать.
  • Он сохраняет только события Web Vitals из исходного набора данных GA4.
  • Идентификатор сеанса, тип пользователя (новый или вернувшийся) и информация об участии в сеансе доступны непосредственно в столбцах.
  • Таблица секционирована по дате и кластеризована по имени метрики. Обычно это уменьшает объем данных, обрабатываемых для каждого запроса.
  • Поскольку для запроса к этой таблице не нужно использовать подстановочные знаки, результаты запроса могут кэшироваться на срок до 24 часов. Это снижает затраты на повторение одного и того же запроса.
  • Если вы используете механизм BigQuery BI, вы можете запускать оптимизированные функции и операторы SQL в этой таблице.

Вы можете напрямую запросить эту материализованную таблицу из пользовательского интерфейса BigQuery или использовать ее в Looker Studio с помощью коннектора BigQuery.

Используйте коннектор Web Vitals

Поскольку создание дашборда с нуля требует много времени, мы разработали комплексное решение, которое создаст для вас шаблон дашборда. Сначала убедитесь, что вы материализовали таблицу Web Vitals с помощью предыдущего запроса. Затем войдите в коннектор Web Vitals для Looker Studio по этой ссылке: goo.gle/web-vitals-connector.

После предоставления однократной авторизации вы должны увидеть следующий экран конфигурации:

Экран авторизации Web Vitals Connector

Укажите материализованный идентификатор таблицы BigQuery (т. е. целевую таблицу) и идентификатор вашего платежного проекта BigQuery. После нажатия кнопки «Подключиться» Looker Studio создаст новую шаблонную панель мониторинга и свяжет с ней ваши данные. Вы можете редактировать, изменять и делиться панелью мониторинга по своему усмотрению. Если вы создаете панель мониторинга один раз, вам не нужно повторно посещать ссылку соединителя, если только вы не хотите создать несколько панелей мониторинга из разных наборов данных.

Перемещаясь по информационной панели, вы можете видеть ежедневные тенденции показателей Web Vitals и некоторую информацию об использовании вашего веб-сайта, такую ​​как пользователи и сеансы, на вкладке «Сводка» .

На вкладке «Анализ пользователей» вы можете выбрать метрику, а затем получить разбивку процентиля метрик, а также количество пользователей по различным показателям использования и бизнеса.

Вкладка «Анализ пути страницы» поможет вам выявить проблемные области на вашем веб-сайте. Здесь вы можете выбрать показатель, чтобы просмотреть обзор. Но вы также видите карту разброса всех путей к страницам со значением процентиля по оси Y и количеством записей по оси X. Карта разброса может помочь выявить страницы, значения показателей которых ниже ожидаемых. Выбрав страницы с помощью точечной диаграммы таблицы путей к страницам , вы можете дополнительно детализировать проблемную область, просмотрев таблицу «Цель отладки» .

Вкладка «Анализ доходов» — это пример того, как вы можете отслеживать показатели своего бизнеса и производительности в одном месте. В этом разделе отображаются все сеансы, в которых пользователь совершил покупку. Вы можете сравнить полученный доход с пользовательским опытом во время конкретного сеанса.

Расширенное использование

По мере того, как вы ближе познакомитесь с набором данных, вы сможете редактировать панель мониторинга и добавлять свои собственные диаграммы для более детального и целенаправленного анализа. Чтобы сделать информационную панель более полезной, вы можете предпринять следующие шаги:

  • Настройте запланированный запрос в BigQuery для получения обновленных данных. Запрос материализации, который мы выполняли ранее, делает только снимок ваших данных на данный момент. Если вы хотите, чтобы ваша панель мониторинга обновлялась новыми данными, вы можете запустить запланированный запрос, который будет выполняться каждый день, и добавлять в материализованную таблицу новые данные.
  • Присоединяйтесь к собственным данным (например, CRM) для получения бизнес-информации. В материализованной таблице можно добавить user_id отдельным столбцом. Это позволит вам присоединиться к своим основным данным. Если ваши собственные данные еще не находятся в BigQuery, вы можете либо загрузить данные , либо использовать интегрированный источник данных .
  • Укажите версию своего сайта или приложения в качестве параметра данных, которые вы отправляете в Google Analytics, и добавьте ее в качестве столбца в материализованной таблице. Затем вы можете добавить эти данные о версии в качестве измерения в свои диаграммы, чтобы было легче увидеть, как изменения версий влияют на производительность.
  • Если вы ожидаете значительно интенсивного использования набора данных посредством прямого запроса или панели управления, вы можете попробовать использовать платную версию BigQuery BI Engine .

Краткое содержание

В этом посте рассказывается об основах использования Google Analytics 4 и BigQuery для измерения и отладки производительности на основе данных реальных пользователей, собранных в полевых условиях. Также объясняется, как создавать автоматизированные отчеты и информационные панели с помощью Looker Studio и Web Vitals Connector, чтобы максимально упростить визуализацию данных.

Некоторые ключевые выводы из этого поста:

  • Измерение производительности с использованием реальных пользовательских данных имеет решающее значение для понимания, отладки и оптимизации вашего сайта.
  • Вы можете получить более глубокое понимание, когда ваши показатели производительности и показатели вашего бизнеса находятся в одной системе. Google Analytics и BigQuery делают это возможным.
  • Экспорт необработанных данных Google Analytics в BigQuery дает вам неограниченные возможности для углубленного индивидуального анализа с использованием языка запросов, который вы, вероятно, уже знаете.
  • У Google есть ряд API и инструментов визуализации, таких как Looker Studio, которые дают вам свободу создавать отчеты именно так, как вы хотите.
,

Узнайте, как отправлять данные Web Vitals в ресурсы Google Analytics 4 и экспортировать данные для анализа в BigQuery и Looker Studio.

Google предоставляет ряд инструментов — Search Console , PageSpeed ​​Insights (PSI) и Chrome User Experience Report (CrUX), — которые позволяют разработчикам видеть, как их сайты работают по сравнению с показателями Core Web Vitals для их реальных пользователей в этой области .

Эти инструменты хороши тем, что дают вам общее представление о реальной производительности вашего сайта и не требуют абсолютно никакой настройки для начала использования.

Однако есть несколько важных причин, по которым вы не хотите полагаться только на эти инструменты для измерения производительности вашего сайта:

  • Инструменты на основе CruX предоставляют данные либо за месяц, либо за предыдущие 28-дневные периоды. Это означает, что вам придется долго ждать после внесения каких-либо изменений, прежде чем вы сможете увидеть результаты.
  • Инструменты на основе CrUX можно сегментировать только по ограниченному числу параметров, таких как страна, тип подключения и категория устройства (настольное или мобильное). Вы не можете разделить данные по параметрам, специфичным для вашего бизнеса (например, вовлеченные пользователи, пользователи в определенной экспериментальной группе и т. д.).
  • Инструменты на основе CrUX могут сказать вам, какова ваша производительность, но они не могут сказать вам, почему . С помощью инструментов аналитики вы можете отправлять дополнительные данные, которые помогут отслеживать и устранять проблемы.

По этим причинам мы рекомендуем всем владельцам сайтов отслеживать показатели Core Web Vitals, используя существующие инструменты аналитики. В этом посте объясняется, как для этого можно использовать бесплатные инструменты, предлагаемые Google.

После того, как вы все настроите, вы сможете создавать такие информационные панели:

Скриншот отчета Web Vitals Connector

Скриншот отчета Web Vitals Connector

Если вам нужен визуальный обзор всех шагов, описанных здесь, ознакомьтесь с нашим докладом на Google I/O '21 :

Мера

Измерение эффективности всегда было возможно с помощью Google Analytics с использованием специальных показателей , но в Google Analytics 4 (GA4) есть несколько новых функций, которые особенно должны интересовать разработчиков.

В то время как веб -интерфейс Google Analytics имеет мощные инструменты анализа, трудно превзойти мощность и гибкость доступа к данным необработанного события, используя язык запроса, который вы, вероятно, уже знаете.

Чтобы начать измерять основные веб -жизненные силы, используя Google Analytics 4 и BigQuery, вам нужно сделать три вещи:

  1. Создайте свойство Google Analytics 4 и проект BigQuery .
  2. Включите экспорт BigQuery в конфигурации свойств Google Analytics, поэтому все полученные вами данные будут автоматически заполнены в ваших таблицах проектов BigQuery.
  3. Добавьте в свой сайт библиотеку JavaScript Web-Vitals , чтобы вы могли измерить основные метрики веб-Vitals и отправить данные в Google Analytics 4 , включая данные атрибуции .

Анализировать

После того, как вы все настроите, вы должны увидеть данные о событиях, заполненные интерфейсом BigQuery, и вы сможете запросить данные, подобные этим:

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

Вот предварительный просмотр результатов этого запроса:

Данные о событиях веб -Vitals в BigQuery

Запрос данных о VITALS

Прежде чем начать запросить данные о событиях в Интернете, важно понять, как агрегируются данные.

Самое важное, что нужно понять, это то, что в некоторых случаях можно получить несколько событий для одной и той же метрики, на одной странице. Это может произойти, если зарегистрируется метрическое значение и сообщается об обновленном значении (общее явление с CLS).

Для событий Web Vitals последнее отправленное значение всегда является наиболее точным, поэтому, прежде чем выполнять какой -либо анализ, важно фильтровать только эти значения. Фрагмент кода, предоставленный библиотекой JavaScript Web-Vitals для отправки данных в Google Analytics 4, включает в себя отправку уникального идентификатора на показатель, чтобы вы могли использовать следующий запрос, чтобы ограничить свои результаты только последним значением для каждого метрического идентификатора:

# 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

10 лучших страниц с худшими CLS (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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

Отлаживать

Предыдущие запросы показывают, как запросить метрические данные Web Vitals, что полезно для понимания вашей текущей производительности и того, как они в тренде с течением времени. Но что вы можете сделать, если ваша производительность хуже, чем ожидалось, но вы не уверены, почему?

Знание того , что такое ваши результаты, не полезно, если вы не можете принять меры и решить проблемы.

Производительность отладки в этой области объясняет, как вы можете отправить дополнительную информацию от отладки с помощью данных аналитики. Если вы следуете инструкциям, подробно описанным в этом посте, вы также увидите, что информация отладки также появляется и в Бигкери.

Пример запросов

Следующие запросы показывают, как использовать параметр события debug_target , чтобы помочь определить основную причину проблем производительности.

Лучшие элементы, способствующие CLS

debug_target - это строка CSS SELECTOR, которая соответствует элементу на странице, которая наиболее актуальна для метрического значения.

С 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 metric_name = 'INP'
WHERE metric_name = 'LCP'

Опять же, вы можете ссылаться на производительность отладки в этой области для инструкций о том, как собирать и отправлять информацию отладки для каждого из основных показателей веб -Vitals.

Визуализировать

Может быть сложно получить информацию, просто посмотрев только на результаты запроса. Например, в следующем запросе перечислены ежедневные 75 -й процентиль для 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

Из этих результатов запроса трудно определить тенденции или выбросы, просто изучая данные.

Результаты запроса на ежедневную метрическую ценность

В таких случаях визуализация данных может помочь вам быстрее получить информацию.

Визуализировать результаты запроса в Looker Studio

BigQuery обеспечивает быстрый способ визуализации любых результатов запроса через Data Studio. Looker Studio - это инструмент для визуализации данных и панели панели, который можно бесплатно использовать. Чтобы визуализировать результаты вашего запроса, после запуска вашего запроса в пользовательском интерфейсе BigQuery нажмите кнопку «Исследовать данные» и выберите «Исследовать» с Like Sudio .

Изучите с помощью Option Studio в BigQuery в BigQuery

Это создаст прямую ссылку от BigQuery в Looker Studio в Explore View. В этом представлении вы можете выбрать поля, которые вы хотите визуализировать, выбрать типы диаграмм, настройки фильтров и создать специальные диаграммы для быстрого визуального анализа. Из предыдущих результатов запроса вы можете создать эту линейную диаграмму, чтобы увидеть тенденцию значений LCP с течением времени:

Линейная диаграмма ежедневных значений LCP в Looker Studio

С помощью этой прямой связи между BigQuery и Looker Studio вы можете создавать быстрые диаграммы из любого из ваших запросов и выполнять визуальный анализ. Однако, если вы хотите провести дополнительный анализ, вы можете посмотреть на несколько диаграмм в интерактивной панели инструментов, чтобы получить более целостный вид или иметь возможность сверлить в данные. Наличие удобной панели инструментов означает, что вам не нужно писать запросы и генерировать диаграммы вручную каждый раз, когда вы хотите анализировать свои метрики.

Вы можете создать приборную панель в Looker Studio, используя нативный разъем BigQuery . Для этого перейдите к DataStudio.google.com , создайте новый источник данных, выберите разъем BigQuery и выберите набор данных, с которым вы хотите работать:

Использование нативного соединителя BigQuery в Looker Studio

Материализация данных о веревках в Интернете

При создании панелей панелей данных о событиях веб -Vitals, как описано ранее, не эффективно использовать набор экспорта Google Analytics 4 напрямую. Из -за структуры данных GA4 и предварительной обработки, необходимой для метриков Web Vitals, части вашего запроса в конечном итоге будут работать несколько раз. Это создает две проблемы: производительность панели панели и стоимость BigQuery.

Вы можете использовать режим BigQuery Sandbox бесплатно. Благодаря свободному уровню использования BigQuery, первый 1 ТБ данных запросов, обработанных в месяц, бесплатно. Для методов анализа, обсуждаемых в этом посте, если вы не используете значительно большой набор данных или регулярно запрашиваете набор данных, вы сможете оставаться в пределах этого свободного лимита каждый месяц. Но если у вас есть веб -сайт с высоким трафиком и вы хотите регулярно отслеживать различные метрики, используя быструю интерактивную панель инструментов, мы предлагаем предварительную обработку и материализацию данных о ваших веб -Vitals, используя при этом функции эффективности 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');

Этот материализованный набор данных имеет несколько преимуществ:

  • Структура данных сплющена и легче запросить.
  • Он сохраняет только события Web Vitals из исходного набора данных GA4.
  • Идентификатор сеанса, тип пользователя (новый против возврата) и информация о взаимодействии сеанса доступна непосредственно в столбцах.
  • Таблица разделена по дате и сгруппирована по метрическому имени. Обычно это уменьшает объем обработанных данных для каждого запроса.
  • Поскольку вам не нужно использовать подстановочные знаки для запроса этой таблицы, результаты запроса могут быть кэшированы в течение 24 часов. Это снижает затраты от повторения того же запроса.
  • Если вы используете двигатель BigQuery BI, вы можете запустить оптимизированные функции SQL и операторы в этой таблице.

Вы можете напрямую запросить эту материализованную таблицу из BigQuery UI или использовать ее в Likeer Studio с помощью разъема BigQuery.

Используйте разъем Web Vitals

Поскольку создание приборной панели с нуля занимает много времени, мы разработали упакованное решение, которое создаст для вас шаблон приборной панели. Сначала убедитесь, что вы материалилировали свою таблицу Vitals, используя предыдущий запрос. Затем обратитесь к разъему Web Vitals для Looker Studio, используя эту ссылку: goo.gle/web-vitals-connector

После предоставления однократного авторизации вы должны увидеть следующий экран конфигурации:

Экран авторизации разъема Web Vitals

Предоставьте материализованный идентификатор таблицы BigQuery (то есть Target Table) и ваш идентификатор BigQuery Billing Project. После нажатия Connect, Looker Studio создаст новую шаблонную панель панели и связывает ваши данные с ней. Вы можете редактировать, изменять и делиться инструментальной панелью, как вам нравится. Если вы один раз создаете приборную панель, вам не нужно снова посещать ссылку на Connector, если вы не хотите создать несколько панелей мониторинга из разных наборов данных.

Когда вы ориентируетесь на приборную панель, вы можете увидеть ежедневные тенденции метриков Web Vitals и некоторую информацию об использовании для вашего веб -сайта, такого как пользователи и сеансы, на вкладке «Краткое описание» .

На вкладке «Анализ пользователя» вы можете выбрать метрику, а затем получить разбивку процентиля метрик, а также подсчет пользователей по различным использованию и бизнес -метрикам.

Вкладка «Анализ страниц» поможет вам определить проблемные области на вашем сайте. Здесь вы можете выбрать метрику, чтобы увидеть обзор. Но вы также видите карту рассеяния всех путей страницы с процентилем по оси Y и учетной записи на оси x. Карта рассеяния может помочь идентифицировать страницы, которые имеют более низкие, чем ожидаемые значения метрики. После выбора страниц, используя диаграмму рассеяния таблицы путей страницы , вы можете дополнительно просверлить задачу, просмотрев целевую таблицу отладки .

Вкладка «Анализ доходов» является примером того, как вы можете отслеживать свой бизнес и показатели эффективности в том же месте. В этом разделе представлены все сеансы, где пользователь совершил покупку. Вы можете сравнить полученный доход и пользовательский опыт во время конкретного сеанса.

Расширенное использование

Когда вы становитесь более знакомым с набором данных, вы можете редактировать панель панели и добавить свои собственные диаграммы для более богатого и целевого анализа. Чтобы сделать панель более полезным, вы можете предпринять следующие шаги:

  • Настройка запланированного запроса в BigQuery для получения обновленных данных. Запрос материализации, который мы запускали ранее, в настоящее время занимает снимки ваших данных. Если вы хотите обновлять свою панель инструментов с помощью новых данных, вы можете запустить запланированный запрос, который будет работать каждый день, и добавлять вашу материализованную таблицу с новыми данными.
  • Присоединяйтесь к первой стороне данных (например, CRM) для бизнеса. В материализованной таблице вы можете добавить user_id в качестве отдельного столбца. Это позволит вам присоединиться к вашим первым данным. Если ваши первые данные еще не находятся в BigQuery, вы можете либо загрузить данные , либо использовать федеративный источник данных .
  • Сообщите о своем сайте или версии приложения в качестве параметра в данных, которые вы отправляете в Google Analytics, и добавьте его в виде столбца в материализованной таблице. Затем вы можете добавить данные версии в качестве измерения в ваших диаграммах, чтобы облегчить изменение версий, влияющие на производительность.
  • Если вы ожидаете значительно сильного использования набора данных с помощью прямого запроса или панели инструментов, вы можете попробовать использовать платную версию BigQuery Bi Engine .

Краткое содержание

В этом посте рассматривались основы использования Google Analytics 4 и BigQuery для измерения и отладки производительности с помощью реальных данных, собранных в этой области. Он также объяснил, как создавать автоматические отчеты и панели панели, используя Likeer Studio и разъем Web Vitals, чтобы сделать визуализацию данных максимально простыми.

Некоторые ключевые выводы из этого поста:

  • Измерение производительности с помощью реальных пользовательских данных имеет решающее значение для понимания, отладки и оптимизации вашего сайта.
  • Вы можете получить более глубокое понимание, когда ваши метрики производительности и ваши бизнес -метрики находятся в той же системе. Google Analytics и BigQuery делают это возможным.
  • BigQuery Export of Raw Google Analytics дает вам неограниченный потенциал для углубленного пользовательского анализа с использованием языка запросов, который вы, вероятно, уже знаете.
  • У Google есть ряд API и инструментов визуализации, таких как Looker Studio, которые дают вам свободу создавать ваши отчеты именно так, как вы хотите, чтобы они были созданы.
,

Узнайте, как отправлять данные Web Vitals в свойства Google Analytics 4 и экспортировать данные для анализа в BigQuery и Looker Studio.

Google предоставляет ряд инструментов - консоли поиска , PageSpeed ​​Insights (PSI) и отчет о опыте пользователя Chrome (CRUX) - который позволяет разработчикам увидеть, как их сайты работают против основных показателей веб -Vitals для своих реальных пользователей в этой области .

Эти инструменты великолепны в том смысле, что они дают вам высокое представление о производительности вашего сайта в реальном пользователе, и они не требуют абсолютно не настройки для начала использования.

Тем не менее, есть несколько важных причин, по которым вы не хотите полагаться только на эти инструменты, чтобы измерить производительность вашего сайта:

  • Данные инструментов на основе сутки от отчетов о либо ежемесячных, так и предыдущих 28-дневных периодах. Это означает, что вам придется ждать долгое время после внесения каких -либо изменений, прежде чем вы сможете увидеть результаты.
  • Инструменты, основанные на крючке, могут быть сегментированы только на ограниченное количество измерений, таких как страна, тип соединения и категория устройств (настольный или мобильный). Вы не можете нарезать данные по измерениям, специфичным для вашего бизнеса (например: привлеченные пользователи, пользователи в конкретной группе экспериментов и т. Д.).
  • Инструменты, основанные на крючке, могут сказать вам, какова ваша производительность, но они не могут сказать вам, почему . С помощью аналитических инструментов вы можете отправить дополнительные данные, чтобы помочь вам отслеживать и отладки проблемы.

По этим причинам мы рекомендуем всем владельцам сайтов отслеживать основные показатели веб -вида, используя их существующий аналитический инструмент. В этом посте объясняется, как вы можете использовать бесплатные инструменты, предлагаемые Google, чтобы сделать именно это.

Как только у вас все настроено, вы сможете создать такие панели мониторинга:

Скриншот отчета о соединении веб -разъема

Скриншот отчета о соединении веб -разъема

И если вам нужен визуальный обзор всех шагов, изложенных здесь, ознакомьтесь с нашим разговором из Google I/O '21 :

Мера

Измерение производительности всегда было возможным с Google Analytics с использованием пользовательских метрик , но в Google Analytics 4 (Gak4) есть несколько новых функций, которые, в частности, должны быть возбуждены разработчики.

В то время как веб -интерфейс Google Analytics имеет мощные инструменты анализа, трудно превзойти мощность и гибкость доступа к данным необработанного события, используя язык запроса, который вы, вероятно, уже знаете.

Чтобы начать измерять основные веб -жизненные силы, используя Google Analytics 4 и BigQuery, вам нужно сделать три вещи:

  1. Создайте свойство Google Analytics 4 и проект BigQuery .
  2. Включите экспорт BigQuery в конфигурации свойств Google Analytics, поэтому все полученные вами данные будут автоматически заполнены в ваших таблицах проектов BigQuery.
  3. Добавьте в свой сайт библиотеку JavaScript Web-Vitals , чтобы вы могли измерить основные метрики веб-Vitals и отправить данные в Google Analytics 4 , включая данные атрибуции .

Анализировать

После того, как вы все настроите, вы должны увидеть данные о событиях, заполненные интерфейсом BigQuery, и вы сможете запросить данные, подобные этим:

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

Вот предварительный просмотр результатов этого запроса:

Данные о событиях веб -Vitals в BigQuery

Запрос данных о VITALS

Прежде чем начать запросить данные о событиях в Интернете, важно понять, как агрегируются данные.

Самое важное, что нужно понять, это то, что в некоторых случаях можно получить несколько событий для одной и той же метрики, на одной странице. Это может произойти, если зарегистрируется метрическое значение и сообщается об обновленном значении (общее явление с CLS).

Для событий Web Vitals последнее отправленное значение всегда является наиболее точным, поэтому, прежде чем выполнять какой -либо анализ, важно фильтровать только эти значения. Фрагмент кода, предоставленный библиотекой JavaScript Web-Vitals для отправки данных в Google Analytics 4, включает в себя отправку уникального идентификатора на показатель, чтобы вы могли использовать следующий запрос, чтобы ограничить свои результаты только последним значением для каждого метрического идентификатора:

# 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

10 лучших страниц с худшими CLS (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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

Отлаживать

Предыдущие запросы показывают, как запросить метрические данные Web Vitals, что полезно для понимания вашей текущей производительности и того, как они в тренде с течением времени. Но что вы можете сделать, если ваша производительность хуже, чем ожидалось, но вы не уверены, почему?

Знание того , что такое ваши результаты, не полезно, если вы не можете принять меры и решить проблемы.

Производительность отладки в этой области объясняет, как вы можете отправить дополнительную информацию от отладки с помощью данных аналитики. Если вы следуете инструкциям, подробно описанным в этом посте, вы также увидите, что информация отладки также появляется и в Бигкери.

Пример запросов

Следующие запросы показывают, как использовать параметр события debug_target , чтобы помочь определить основную причину проблем производительности.

Лучшие элементы, способствующие CLS

debug_target - это строка CSS SELECTOR, которая соответствует элементу на странице, которая наиболее актуальна для метрического значения.

С 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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 metric_name = 'INP'
WHERE metric_name = 'LCP'

Опять же, вы можете ссылаться на производительность отладки в этой области для инструкций о том, как собирать и отправлять информацию отладки для каждого из основных показателей веб -Vitals.

Визуализировать

Может быть сложно получить информацию, просто посмотрев только на результаты запроса. Например, в следующем запросе перечислены ежедневные 75 -й процентиль для 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 *, ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') ORDER BY (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'metric_start_time') DESC
    ) = 1 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

Из этих результатов запроса трудно определить тенденции или выбросы, просто изучая данные.

Результаты запроса на ежедневную метрическую ценность

В таких случаях визуализация данных может помочь вам быстрее получить информацию.

Визуализировать результаты запроса в Looker Studio

BigQuery обеспечивает быстрый способ визуализации любых результатов запроса через Data Studio. Looker Studio - это инструмент для визуализации данных и панели панели, который можно бесплатно использовать. Чтобы визуализировать результаты вашего запроса, после запуска вашего запроса в пользовательском интерфейсе BigQuery нажмите кнопку «Исследовать данные» и выберите «Исследовать» с Like Sudio .

Изучите с помощью Option Studio в BigQuery в BigQuery

Это создаст прямую ссылку от BigQuery в Looker Studio в Explore View. В этом представлении вы можете выбрать поля, которые вы хотите визуализировать, выбрать типы диаграмм, настройки фильтров и создать специальные диаграммы для быстрого визуального анализа. Из предыдущих результатов запроса вы можете создать эту линейную диаграмму, чтобы увидеть тенденцию значений LCP с течением времени:

Линейная диаграмма ежедневных значений LCP в Looker Studio

С помощью этой прямой связи между BigQuery и Looker Studio вы можете создавать быстрые диаграммы из любого из ваших запросов и выполнять визуальный анализ. Однако, если вы хотите провести дополнительный анализ, вы можете посмотреть на несколько диаграмм в интерактивной панели инструментов, чтобы получить более целостный вид или иметь возможность сверлить в данные. Наличие удобной панели инструментов означает, что вам не нужно писать запросы и генерировать диаграммы вручную каждый раз, когда вы хотите анализировать свои метрики.

Вы можете создать приборную панель в Looker Studio, используя нативный разъем BigQuery . Для этого перейдите к DataStudio.google.com , создайте новый источник данных, выберите разъем BigQuery и выберите набор данных, с которым вы хотите работать:

Использование нативного соединителя BigQuery в Looker Studio

Материализация данных о веревках в Интернете

При создании панелей панелей данных о событиях веб -Vitals, как описано ранее, не эффективно использовать набор экспорта Google Analytics 4 напрямую. Из -за структуры данных GA4 и предварительной обработки, необходимой для метриков Web Vitals, части вашего запроса в конечном итоге будут работать несколько раз. Это создает две проблемы: производительность панели панели и стоимость BigQuery.

Вы можете использовать режим BigQuery Sandbox бесплатно. Благодаря свободному уровню использования BigQuery, первый 1 ТБ данных запросов, обработанных в месяц, бесплатно. Для методов анализа, обсуждаемых в этом посте, если вы не используете значительно большой набор данных или регулярно запрашиваете набор данных, вы сможете оставаться в пределах этого свободного лимита каждый месяц. Но если у вас есть веб -сайт с высоким трафиком и вы хотите регулярно отслеживать различные метрики, используя быструю интерактивную панель инструментов, мы предлагаем предварительную обработку и материализацию данных о ваших веб -Vitals, используя при этом функции эффективности 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');

Этот материализованный набор данных имеет несколько преимуществ:

  • Структура данных сплющена и легче запросить.
  • Он сохраняет только события Web Vitals из исходного набора данных GA4.
  • Идентификатор сеанса, тип пользователя (новый против возврата) и информация о взаимодействии сеанса доступна непосредственно в столбцах.
  • Таблица разделена по дате и сгруппирована по метрическому имени. Обычно это уменьшает объем обработанных данных для каждого запроса.
  • Поскольку вам не нужно использовать подстановочные знаки для запроса этой таблицы, результаты запроса могут быть кэшированы в течение 24 часов. Это снижает затраты от повторения того же запроса.
  • Если вы используете двигатель BigQuery BI, вы можете запустить оптимизированные функции SQL и операторы в этой таблице.

Вы можете напрямую запросить эту материализованную таблицу из BigQuery UI или использовать ее в Likeer Studio с помощью разъема BigQuery.

Используйте разъем Web Vitals

Поскольку создание приборной панели с нуля занимает много времени, мы разработали упакованное решение, которое создаст для вас шаблон приборной панели. Сначала убедитесь, что вы материалилировали свою таблицу Vitals, используя предыдущий запрос. Затем обратитесь к разъему Web Vitals для Looker Studio, используя эту ссылку: goo.gle/web-vitals-connector

После предоставления однократного авторизации вы должны увидеть следующий экран конфигурации:

Экран авторизации разъема Web Vitals

Предоставьте материализованный идентификатор таблицы BigQuery (то есть Target Table) и ваш идентификатор BigQuery Billing Project. После нажатия Connect, Looker Studio создаст новую шаблонную панель панели и связывает ваши данные с ней. Вы можете редактировать, изменять и делиться инструментальной панелью, как вам нравится. Если вы один раз создаете приборную панель, вам не нужно снова посещать ссылку на Connector, если вы не хотите создать несколько панелей мониторинга из разных наборов данных.

Когда вы ориентируетесь на приборную панель, вы можете увидеть ежедневные тенденции метриков Web Vitals и некоторую информацию об использовании для вашего веб -сайта, такого как пользователи и сеансы, на вкладке «Краткое описание» .

На вкладке «Анализ пользователя» вы можете выбрать метрику, а затем получить разбивку процентиля метрик, а также подсчет пользователей по различным использованию и бизнес -метрикам.

Вкладка «Анализ страниц» поможет вам определить проблемные области на вашем сайте. Здесь вы можете выбрать метрику, чтобы увидеть обзор. Но вы также видите карту рассеяния всех путей страницы с процентилем по оси Y и учетной записи на оси x. Карта рассеяния может помочь идентифицировать страницы, которые имеют более низкие, чем ожидаемые значения метрики. После выбора страниц, используя диаграмму рассеяния таблицы путей страницы , вы можете дополнительно просверлить задачу, просмотрев целевую таблицу отладки .

Вкладка «Анализ доходов» является примером того, как вы можете отслеживать свой бизнес и показатели эффективности в том же месте. В этом разделе представлены все сеансы, где пользователь совершил покупку. Вы можете сравнить полученный доход и пользовательский опыт во время конкретного сеанса.

Расширенное использование

Когда вы становитесь более знакомым с набором данных, вы можете редактировать панель панели и добавить свои собственные диаграммы для более богатого и целевого анализа. Чтобы сделать панель более полезным, вы можете предпринять следующие шаги:

  • Настройка запланированного запроса в BigQuery для получения обновленных данных. Запрос материализации, который мы запускали ранее, в настоящее время занимает снимки ваших данных. Если вы хотите обновлять свою панель инструментов с помощью новых данных, вы можете запустить запланированный запрос, который будет работать каждый день, и добавлять вашу материализованную таблицу с новыми данными.
  • Присоединяйтесь к первой стороне данных (например, CRM) для бизнеса. В материализованной таблице вы можете добавить user_id в качестве отдельного столбца. Это позволит вам присоединиться к вашим первым данным. Если ваши первые данные еще не находятся в BigQuery, вы можете либо загрузить данные , либо использовать федеративный источник данных .
  • Сообщите о своем сайте или версии приложения в качестве параметра в данных, которые вы отправляете в Google Analytics, и добавьте его в виде столбца в материализованной таблице. Затем вы можете добавить данные версии в качестве измерения в ваших графиках, чтобы облегчить изменение версий, влияют на производительность.
  • Если вы ожидаете значительно сильного использования набора данных с помощью прямого запроса или панели инструментов, вы можете попробовать использовать платную версию BigQuery Bi Engine .

Краткое содержание

В этом посте рассматривались основы использования Google Analytics 4 и BigQuery для измерения и отладки производительности с помощью реальных данных, собранных в этой области. Он также объяснил, как создавать автоматические отчеты и панели панели, используя Likeer Studio и разъем Web Vitals, чтобы сделать визуализацию данных максимально простыми.

Некоторые ключевые выводы из этого поста:

  • Измерение производительности с помощью реальных пользовательских данных имеет решающее значение для понимания, отладки и оптимизации вашего сайта.
  • Вы можете получить более глубокое понимание, когда ваши метрики производительности и ваши бизнес -метрики находятся в той же системе. Google Analytics и BigQuery делают это возможным.
  • BigQuery Export of Raw Google Analytics дает вам неограниченный потенциал для углубленного пользовательского анализа с использованием языка запросов, который вы, вероятно, уже знаете.
  • У Google есть ряд API и инструментов визуализации, таких как Looker Studio, которые дают вам свободу создавать ваши отчеты именно так, как вы хотите, чтобы они были созданы.