Отслеживание основных показателей веб-сайта и устранение неполадок с помощью Google Analytics 4 и BigQuery
Из этого руководства вы узнаете, как отправлять данные Core Web Vitals в ресурсы Google Analytics 4 и экспортировать их для анализа в BigQuery и Looker Studio.
Материал основан на трех интереснейших публикациях и будет полезен не только специалистам по поисковой оптимизации (SEO), но и самим владельцам сайтов:
- Measure and debug performance with Google Analytics 4 and BigQuery (авторы - Minhaz Kazi, Philip Walton)
- Core Web Vitals Tracking via GA4, BigQuery and Google Data Studio (автор - Tony McCreath)
- Track Core Web Vitals In GA4 With Google Tag Manager (автор - Simo Ahava)
Что такое Core Web Vitals?
На конференции Google I/O в 2021 году команда web.dev представила свою презентацию Core Web Vitals, в которой показала, как отслеживать эффективность основных показателей веб-сайта и отлаживать производительность с помощью Google Analytics 4 и BigQuery. Если кратко, то речь в докладе шла о том, как создать мощную приборную панель Core Web Vitals в Looker Studio, используя данные ресурса GA4 о посетителях собственного веб-сайта и соответствующие SQL-запросы. Все это было подкреплено техническим руководством, ссылку на которое я приложил в самом начале этой статьи.
Результатом выступления стала демонстрация той самой приборной панели Looker Studio с метриками Core Web Vitals:
Какой практический смысл во всех этих индикаторах и настройках? Google предоставляет владельцам сайтов ряд инструментов - Search Console, PageSpeed Insights (PSI) и Chrome User Experience Report (CrUX), позволяющих разработчикам видеть, насколько их сайты удобны для пользователей в Интернете.
Удобство оценивается по показателям Core Web Vitals:
- скорость загрузки (loading);
- интерактивность (interactivity);
- визуальная стабильность (visual stability).
И включает в себя следующие показатели (и их соответствующие пороговые значения):
- LCP (Largest Contentful Paint) / скорость загрузки. Указывает на время, в течение которого осуществляется отрисовка крупного контента (самый большой видимый элемент в зоне просмотра). Расчет начинается сразу после того, как пользователь запрашивает URL-адрес страницы. В качестве крупного контента может браться не только видеоролик или картинка, но и большой блок с текстом. Чтобы страницей было удобно пользоваться, это значение должно составлять менее 2,5 секунд с начала загрузки страницы;
- CLS (Cumulative Layout Shift) / визуальная стабильность. Измеряет, насколько контент смещается на экране после отображения. Если смещения нет – показатель равен нулю, что хорошо, ведь чем выше значение, тем менее удобно пользователю взаимодействовать со страницей. Если простыми словами – речь идет про визуальную стабильность. Чтобы страницей было удобно пользоваться, значение CLS должно составлять менее 0,1;
- INP (Interaction to Next Paint) / интерактивность. Оценивает общую отзывчивость страницы на взаимодействия с пользователем путем наблюдения за задержкой всех действий с помощью щелчков, касаний и клавиатуры, которые происходят на протяжении всего периода посещения пользователем страницы. Окончательное значение INP представляет собой самое продолжительное наблюдаемое взаимодействие без учета выбросов. Чем ниже показатель INP, тем качественнее работа страницы: более низкий показатель INP указывает на более быстрое время отклика. Чтобы сайтом было удобно пользоваться, страницы должны иметь INP 200 миллисекунд или меньше.
Примечание: ранее к показателям Core Web Vitals относился FID (First Input Delay), который учитывал время между первым взаимодействием посетителя со страницей (нажатие на ссылку, кнопку, другие), а также ответом браузера (момента, когда он фактически может начать обработку). Однако в марте 2024 года его заменил показатель Interaction to Next Paint (INP). Окончательно поддержка FID закончилась 9 сентября 2024 года.
Таким образом:
- INP (Interaction to Next Paint) - измеряет время отклика;
- LCP (Largest Contentful Paint) - измеряет время загрузки страницы;
- CLS (Cumulative Layout Shift) - измеряет визуальную стабильность.
Google настоятельно рекомендует владельцам сайтов следить за показателями Core Web Vitals. Это не только обеспечивает успех в работе с Поиском, но и в целом повышает удобство страницы. В самом простом понимании, Core Web Vitals - это группа определенных факторов (показателей), влияющих на ранжирование вашего веб-сайта в поисковой выдаче Google (на SEO).
Если вы используете Search Console, то наверняка знаете про отчет Core Web Vitals:
Он основан на данных о сеансах реальных посетителей и позволяет понять, насколько эффективно работают страницы сайта. В отчете Core Web Vitals приводятся данные об эффективности страниц, сгруппированные по статусу (Низкая скорость, Нужно увеличить скорость или Хорошо), показателям (CLS, INP и LCP) и группам URL. Сведения приводятся только по индексированным URL, по фактическому, а не каноническому URL, поскольку именно он фигурирует в большинстве других отчетов.
Эта информация, в свою очередь, поступает из другого отчета - CrUX, в котором собрана анонимная информация о скорости загрузки ваших URL при посещении их реальными пользователями. В самой базе данных этого отчета информация о URL собирается независимо от того, связаны ли они с ресурсом Search Console.
Отчет об опыте пользователя Google Chrome (также известный как отчет Chrome UX или сокращенно CrUX) - это набор данных, который отражает то, как реальные пользователи Chrome взаимодействуют с популярными местами в Интернете. Данные CrUX собираются из реальных браузеров по всему миру на основе определенных параметров (например, тип соединения (Offline, 2G, 3G, 4G и т.д.) и страна) и показателей браузера (LCP, CLS, INP, DOMContentLoaded и др.), которые позволяют владельцам сайтов определить, как пользователи воспринимают их сайты. Таким образом, в отчете представлены данные по всем запросам из всех местоположений. Если значительный объем вашего трафика поступает из страны с низкой скоростью подключений к интернету, то эффективность ваших страниц в целом снизится.
Инструмент PageSpeed Insights анализирует веб-страницы, выявляет их слабые места и предлагает решение для ускорения загрузки страниц. Удобен и прост в применении. Система не измеряет скорость загрузки страницы, а оценивает показатели, которые могут на нее влиять.
Существует и другой инструмент оценки удобства страниц вашего сайта - Lighthouse. Вы можете запустить его на любой веб-странице, общедоступной или требующей аутентификации. Он проводит аудит производительности, доступности, прогрессивных веб-приложений, SEO и многого другого.
Отчет предоставляет лабораторные данные, то есть собственный опыт разработчиков. Это хорошо для детального анализа и тестирования, но не отражает точно опыт ваших реальных посетителей, у которых будут разные сетевые подключения из разных мест с разных устройств. Пользователи также взаимодействуют со страницами, в отличие от этих инструментов тестирования.
Все приведенные выше инструменты хороши тем, что дают вам общее представление о реальной производительности вашего сайта и не требуют абсолютно никакой настройки для начала использования. Однако есть несколько важных причин, по которым вы не можете полагаться только на эти инструменты для измерения производительности вашего сайта:
- данные на основе инструментов CrUX сильно агрегированы, их можно сегментировать только по ограниченному числу параметров, таких как страна, тип подключения и категория устройства (настольное или мобильное). Вы получаете только общее представление о своей производительности. Во многих случаях вы не получите данные на уровне страниц и должны будете работать с данными на уровне источника (домена);
- результаты также являются средними за последние 28 дней, что означает, что существует большая задержка между внесением изменений и полным отображением их эффекта в отчете. Чтобы страницы были включены в отчет, их должно посетить пороговое количество зарегистрированных пользователей Chrome за 28 дней;
- отчет Core Web Vitals в Search Console основан на данных CrUX, а не на индексе поиска Google. Он не имеет ничего общего с индексацией страницы для поиска. Нередко сайты с низким трафиком не видят URL-адресов в этом отчете из-за отсутствия данных CrUX, и могут произойти резкие изменения в количестве URL-адресов. Это не означает, что эти URL-адреса больше не показываются в поиске;
- инструменты на основе CrUX могут сказать вам, какова ваша производительность, но они не могут сказать вам, почему. С помощью инструментов аналитики вы можете отправлять дополнительные данные, которые помогут отслеживать и устранять проблемы.
Именно по этим причинам Google рекомендует всем владельцам сайтов отслеживать показатели Core Web Vitals, используя свой собственный ресурс Google Analytics 4. В этом и есть ключевое преимущество и отличие от текущих инструментов - отправляя данные в GA4 и экспортируя их потом в BigQuery, вы сможете видеть детализированную информацию на уровне просмотра страниц для всех посетителей, которых можно отслеживать. Это позволит быстрее обнаруживать проблемы и устранять неполадки в работе вашего сайта.
Чтобы начать отслеживать основные веб-показатели с помощью Google Analytics 4 и BigQuery, вам нужно сделать три вещи:
- создать ресурс Google Analytics 4 и проект BigQuery;
- настроить связь GA4 и BigQuery, чтобы все полученные данные автоматически заполнялись в таблицах вашего проекта BigQuery;
- добавить на свой сайт библиотеку JavaScript Web-Vitals, чтобы можно было измерять основные показатели Web-Vitals и отправлять данные в Google Analytics 4, включая данные атрибуции.
Предполагаю, что у вас уже есть счетчик Google Analytics 4 и проект BigQuery с настроенной связью. Поэтому данные шаги я целенаправленно опускаю. В этом руководстве мы сосредоточимся на последней настройке - отслеживании показателей Core Web Vitals.
Отслеживание с помощью gtag.js
web.dev имеет репозиторий на GitHub, в котором размещены различные фрагменты кодов. Их вы можете использовать для отслеживания показателей Core Web Vitals. Tony McCreath, разработчик BigCommerce и автор материала, на основе которого я написал это руководство, дополнил официальный скрипт некоторыми деталями.
Если вы используете тег Google gtag.js, установленный напрямую (без использования Google Tag Manager), разместите нижеприведенный код на всех страницах вашего сайта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<script id="web-vitals-ga4"> /* * Send Core Web Vitals to Google Analytics 4 using gtag * v3.2 */ function sendToGoogleAnalytics({name, delta, value, id, entries, rating, attribution}) { // Assumes the global `gtag()` function exists, see: // https://developers.google.com/analytics/devguides/collection/ga4 var debugTarget = attribution ? attribution.largestShiftTarget||attribution.element||attribution.eventTarget||'' : '(not set)'; gtag('event', name, { // Built-in params: value: delta, // Use `delta` so the value can be summed. // Custom params: metric_id: id, // Needed to aggregate events. metric_value: value, // Optional. metric_delta: delta, // Optional. // OPTIONAL: any additional params or debug info here. // See: https://web.dev/debug-web-vitals-in-the-field/ // metric_rating: 'good' | 'needs-improvement' | 'poor'. 'needs-improvement' was 'ni' metric_rating: rating, // debug_info debug_target: debugTarget, debug_event_type: attribution ? attribution.eventType||'' : '', debug_timing: attribution ? attribution.loadState||'' : '', event_time: attribution ? attribution.largestShiftTime||(attribution.lcpEntry&&attribution.lcpEntry.startTime)||attribution.eventTime||'': '' }); } </script> <script id="web-vitals-cdn"> /* * Using the web-vitals script from a CDN * * https://github.com/GoogleChrome/web-vitals#from-a-cdn * * Modified to call the sendToGoogleAnalytics function on events * */ (function() { var script = document.createElement('script'); script.src = 'https://unpkg.com/web-vitals@3.0.0/dist/web-vitals.attribution.iife.js'; script.onload = function() { // When loading `web-vitals` using a classic script, all the public // methods can be found on the `webVitals` global namespace. webVitals.onCLS(sendToGoogleAnalytics); webVitals.onFID(sendToGoogleAnalytics); webVitals.onLCP(sendToGoogleAnalytics); webVitals.onFCP(sendToGoogleAnalytics); webVitals.onTTFB(sendToGoogleAnalytics); webVitals.onINP(sendToGoogleAnalytics); } document.head.appendChild(script); }()) </script> |
Он отправляет нужные события для Core Web Vitals в ваш ресурс GA4. Код может быть добавлен где угодно, но наиболее распространенный вариант - после вашего базового кода GA4.
Несомненно, отслеживание типов страниц (Page Type) может быть очень полезным для сегментации данных и сужения круга проблемных частей веб-сайта, так же, как и сбор информации об эффективном типе подключения пользователя (например, 4G), если он запросил сохранение данных, а также сведения о ширине и высоте дисплея экрана посетителя.
Чтобы включить эти данные в отслеживание, вам нужно изменить ваш основной gtag для отправки параметров page_type, effective_connection_type, save_data, width и height.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<script> function getEffectiveConnectionType(){ var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; if(connection && connection.effectiveType) return connection.effectiveType; return 'unknown'; } function getSaveData() { var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; if(connection && connection.saveData) return connection.saveData; return 'unknown'; } </script> <!-- Global site tag (gtag.js) - Google Analytics --> <script async="async" src="https://www.googletagmanager.com/gtag/js?id=G-0BQR1PRHYJ"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-0BQR1PRHYJ', { page_type: 'PAGE TYPE NAME', effective_connection_type: getEffectiveConnectionType(), save_data: getSaveData(), width: window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth, height: window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight }); </script> |
Изменения выделены зеленым цветом. Не забудьте заменить PAGE TYPE NAME (отмечено красным) на ваш код, чтобы динамически получать тип/категорию страницы. То, как вы устанавливаете page_type, зависит от вашей CMS и того, как вы хотите сегментировать свои страницы. Например, статьи, относящиеся к блогу - могут иметь тип Article, товары - Products, услуги - Services, результаты поиска - Search и т.д. и т.п. Функционал чем-то схож с настройкой групп контента в Google Analytics 4.
После добавления кода Тони вы будете отправлять те же события и параметры Core Web Vitals, которые используются в решении от web.dev. Сюда входят стандартные метрики (metric_id, metric_value, metric_delta), параметры отладки (debug_target, debug_event_type, debug_timing, event_time), рейтинг для метрики (metric_rating) и необязательный параметр page_type.
Отслеживание с помощью Google Tag Manager
Существует несколько пользовательских шаблонов Google Tag Manager для отслеживания показателей Core Web Vitals. Это:
- Core Web Vitals от Симо Ахавы. Подробнее по использованию и установке см. его руководство;
- Шаблон Web Vitals от команды Google Marketing Solutions. Инструкции по использованию и установке см. в файле README.
Вы можете попробовать реализовать это одним из приведенных способов. А можете взять за основу другое решение - от Tony McCreath. Именно его я буду подробнее описывать далее. Оно очень похоже на отслеживание с помощью тега gtag.js, только отправка данных Core Web Vitals осуществляется с использованием уровня данных (dataLayer). Тони взял за основу названия событий, ориентируясь на руководство Симо Ахавы, чтобы их решения были совместимыми.
Перейдите в контейнер GTM и создайте тег типа Пользовательский HTML. Вставьте в него нижеприведенный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<script id="web-vitals-ga4"> /* * Send Core Web Vitals to the DataLayer * v3.3 */ function sendToDataLayer(metric) { var rating = metric.rating; var attribution = metric.attribution; var debugTarget = attribution ? attribution.largestShiftTarget||attribution.element||attribution.eventTarget||'' : '(not set)'; var webVitalsMeasurement = { name: metric.name, id: metric.id, value: metric.value, delta: metric.delta, rating: rating, valueRounded: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value), deltaRounded: Math.round(metric.name === 'CLS' ? metric.delta * 1000 : metric.delta), debugTarget: debugTarget, debug_event_type: attribution ? attribution.eventType||'' : '', debugTiming: attribution ? attribution.loadState||'' : '', eventTime: attribution ? attribution.largestShiftTime||(attribution.lcpEntry&&attribution.lcpEntry.startTime)||attribution.eventTime||'': '' }; dataLayer.push({ event: 'coreWebVitals', webVitalsMeasurement: webVitalsMeasurement }); } </script> <script id="web-vitals-cdn"> /* * Using the web-vitals script from a CDN * * https://github.com/GoogleChrome/web-vitals#from-a-cdn * * Modified to call the sendToDataLayer function on events * */ (function() { var script = document.createElement('script'); script.src = 'https://unpkg.com/web-vitals@3.0.0/dist/web-vitals.attribution.iife.js'; script.onload = function() { // When loading `web-vitals` using a classic script, all the public // methods can be found on the `webVitals` global namespace. webVitals.onCLS(sendToDataLayer); webVitals.onFID(sendToDataLayer); webVitals.onLCP(sendToDataLayer); webVitals.onFCP(sendToDataLayer); webVitals.onTTFB(sendToDataLayer); webVitals.onINP(sendToDataLayer); } document.head.appendChild(script); }()) </script> |
В расширенных настройках тега в Последовательность активации тегов добавьте Тег setup Google Analytics 4, чтобы ваш тег Google загружался перед текущим тегом. Это нужно для того, чтобы не отправлять события в GA4 до того, как он будет существовать. В качестве триггер активации выберите триггер All Pages (Все страницы).
В Google Tag Manager это будет выглядеть так:
Сохраните тег. Теперь нам нужно определить все пользовательские переменные, которые мы отправляем в dataLayer. Тони последовал примеру Симо Ахавы и использовал его наименования.
Примечание: на будущее обратите внимание, что отчет Тони в Looker Studio по показателям Core Web Vitals не использует округленные значения, но он сохранил их для совместимости с другими решениями.
Перейдите в раздел Переменные и создайте поочередно пользовательские переменные типа Переменная уровня данных. Это нужно сделать для каждой из таблицы ниже, задав им соответствующие имена:
Название переменной | Имя переменной уровня данных |
---|---|
DLV – webVitalsMeasurement.name | webVitalsMeasurement.name |
DLV – webVitalsMeasurement.id | webVitalsMeasurement.id |
DLV – webVitalsMeasurement.value | webVitalsMeasurement.value |
DLV – webVitalsMeasurement.delta | webVitalsMeasurement.delta |
DLV – webVitalsMeasurement.valueRounded | webVitalsMeasurement.valueRounded |
DLV – webVitalsMeasurement.deltaRounded | webVitalsMeasurement.deltaRounded |
DLV – webVitalsMeasurement.debugTarget | webVitalsMeasurement.debugTarget |
DLV – webVitalsMeasurement.debugEventType | webVitalsMeasurement.debugEventType |
DLV – webVitalsMeasurement.debugTiming | webVitalsMeasurement.debugTiming |
DLV – webVitalsMeasurement.eventTime | webVitalsMeasurement.eventTime |
DLV – webVitalsMeasurement.rating | webVitalsMeasurement.rating |
Пример переменной уровня данных DLV – webVitalsMeasurement.name:
Всего должно получиться 11 переменных уровня данных:
После этого перейдите в раздел Триггеры и создайте триггер типа Специальное событие с именем coreWebVitals:
Все, что осталось сделать - это создать тег типа Google Аналитика: событие GA4. Задайте ваш идентификатор потока данных GA4. В качестве названия события используйте переменную уровня данных DLV – webVitalsMeasurement.name. Добавьте параметры события с названиями и значениями, как это указано в таблице ниже:
Параметр события | Значение |
---|---|
metric_name | {{DLV – webVitalsMeasurement.name}} |
metric_id | {{DLV – webVitalsMeasurement.id}} |
metric_value | {{DLV – webVitalsMeasurement.value}} |
value | {{DLV – webVitalsMeasurement.delta}} |
metric_delta | {{DLV – webVitalsMeasurement.delta}} |
debug_target | {{DLV – webVitalsMeasurement.debugTarget}} |
debug_event_type | {{DLV – webVitalsMeasurement.debugEventType}} |
debug_timing | {{DLV – webVitalsMeasurement.debugTiming}} |
event_time | {{DLV – webVitalsMeasurement.eventTime}} |
metric_rating | {{DLV – webVitalsMeasurement.rating}} |
В качестве триггера активации добавьте триггер специального события, созданный на предыдущем шаге. Итоговый тег события GA4 с отслеживанием показателей Core Web Vitals будет выглядеть так:
Как и в случае с реализацией gtag.js, вы можете отправлять параметр page_type в Google Analytics 4, чтобы иметь возможность сегментировать свой отчет по тип страницы. То, как вы будете определять значение page_type, зависит от вас. Затем вам нужно будет отправить его в dataLayer, создать для него переменную и добавить ее в параметр конфигурации GA4.
Для настройки эффективного типа подключения необходимо создать пользовательскую переменную типа Собственный код JavaScript:
1 2 3 4 5 |
function () { var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; if (connection && connection.effectiveType) return connection.effectiveType; return 'unknown'; } |
Назовите переменную CJS - Effective connection type:
А затем добавьте ее в тег Google, задав параметр конфигурации effective_connection_type:
Аналогичным образом вы можете создать переменную с функцией, которая проверяет, поддерживает ли устройство возможность экономии данных:
1 2 3 4 5 |
function () { var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; if (connection && connection.saveData) return connection.saveData; return 'unknown'; } |
И точно таким же образом добавить ее в параметр конфигурации тега Google. Таки образом, все события будут возвращать page_type, effective_connection_type и save_data.
Следуя примеру отслеживания с помощью gtag.js, можно добавить еще ширину (width) и высоту (height). Но это вы можете сделать уже индивидуально.
Файл контейнера GTM со всеми объектами вы можете скачать по ссылке ниже, а затем импортировать его к себе в рабочую область.
Проверка настроек
Сохраните все изменения. Воспользовавшись режимом предварительного просмотра, перейдите к себе на сайт. На шкале событий вы должны увидеть несколько событий coreWebVitals. Нажав на одно из них, вы можете раскрыть Вызов API и посмотреть какие значения отображаются в dataLayer:
Каждый из них имеет определенный набор метрик для ключевых показателей Core Web Vitals. Один для CLS, другой для LCP, третий для INP, и так далее.
В детальных сведениях о теге события GA4 вы должны увидеть все значения метрик, которые добавили как параметры события:
И, конечно же, события по мере их регистрации вы сможете увидеть в отчете В реальном времени:
Создание специальных определений
Этот шаг не является обязательным, но я рекомендую перейти в Google Analytics 4 и создать специальные определения для каждой метрики, которую мы передаем с помощью тега события GA4.
Специальные параметры
Специальный параметр | Область действия | Описание | Параметр события |
---|---|---|---|
Web Vitals metric ID | Событие | Используется для группировки веб-показателей, которые появляются на одной странице | metric_id |
Debug target | Событие | Определяет путь селектора к элементу, который внес наибольший вклад | debug_target |
Debug timing | Событие | Для событий FID указывается, произошло ли событие до «pre_dcl» или после «post_dcl», когда был загружен контент | debug_timing |
Event time | Событие | Время, когда произошло событие Web Vitals | event_time |
Web Vitals rating | Событие | «Хорошо», «Требует улучшения» или «Плохо». На основе оценок, выставленных web.dev. Используется в событиях LCP, CLS, FID | metric_rating |
Page type | Событие | Используется для определения типа страницы (для сегментации отчетов на основе страниц) | page_type |
Effective connection type | Событие | Используется для получения эффективной скорости соединения пользователя. 4G, 3G, 2G, SLOW-2G и unknown | effective_connection_type |
Save data | Событие | Используется для получения доступа к информации о предпочтениях пользователя в отношении экономии данных | save_data |
Пример специального параметра в интерфейсе Google Analytics 4:
Специальные показатели
Специальный показатель | Область действия | Описание | Параметр события | Единица измерения |
---|---|---|---|---|
Web Vitals value | Событие | Значение показателя Web Vitals. Используется в событиях LCP, FID и CLS | metric_value | Стандартные |
Web Vitals delta | Событие | Разница с последнего отчета по этому показателю. 'value' также установлено на дельту | metric_delta | Стандартные |
Пример специального показателя в интерфейсе Google Analytics 4:
Подключение к Google BigQuery
Как я писал ранее, в этом руководстве я не планирую повторяться и описывать этапы подключения Google Analytics 4 к BigQuery. Вы можете почитать другие материалы моего блога, в которых подробно прописаны все инструкции:
У вас должен быть создан проект в Google Cloud и установлена связь Google Analytics 4 и BigQuery:
После завершения настройки может потребоваться около 24 часов, чтобы создать вашу первую таблицу экспорта GA4. В самом BigQuery, по мере регистрации событий, вы должны видеть данные в соответствующих таблицах events_, включая события с показателями Core Web Vitals:
Самый простой способ найти такие события - это использовать нижеприведенный SQL-запрос:
1 2 |
SELECT * FROM `my_project_id.analytics_XXXXX.events_*` WHERE event_name IN ('LCP', 'INP', 'CLS') |
, где my_project_id.analytics_XXXXX.events_* - путь к вашей таблице в BigQuery.
Результат выполнения:
Мы могли бы использовать встроенный коннектор Google Analytics 4 в Looker Studio. Однако в таком способе есть серьезные ограничения:
- ненадежное сопоставление специальных определений GA4 с полями Looker Studio. Изменение источника данных приводит к перемешиванию полей в отчете. Таким образом, вы не сможете использовать мой шаблон Looker Studio (а я Тони) для копирования и вставки в него своих собственных данных;
- Looker Studio не имеет механизма для группировки событий Core Web Vitals по просмотру страницы, чтобы определить окончательное значение.
Именно поэтому нам нужен BigQuery для предварительной группировки данных.
Примечание: с 9 сентября 2024 г. Google прекратила работу BigQuery и Looker Studio в России. Помимо этого, перед тем, как выполнять следующие шаги, у вас должен быть активный проект в Google Cloud с подключенным платежным биллингом. Если вы этого не сделаете, то не сможете полноценно работать с BigQuery. На момент публикации этого материала вы не сможете привязать свою банковскую карту, выпущенную на территории РФ. Наиболее простое и эффективное решение - выпустить карту другой страны (Казахстан, Киргизия, Армения и т.д.), чтобы иметь возможность пользоваться Google Cloud и оплачивать счета.
Создание материализованной таблицы BigQuery
После того, как вы настроили связь Google Analytics 4 с BigQuery и убедились, что данные по событиям Core Web Vitals экспортируются в таблицы вашего проекта, пришло время перейти к следующему шагу. Нам нужно преобразовать данные, чтобы их можно было легко использовать в Looker Studio. Главная задача - вывести окончательные метрики Core Web Vitals для каждого просмотра страницы, чтобы Looker Studio мог с ними справиться.
Мы выполняем это преобразование, добавляя SQL-запрос, который создает новую таблицу с нужными нам данными. Запрос, который мы используем, основан на запросе, представленном в технической документации web.dev, с несколькими дополнениями, добавленными для поддержки отчета Tony McCreath. Для этого будут использоваться материализованные представления BigQuery.
BigQuery Materialized View - это предварительно зафиксированные представления, которые периодически кэшируют результаты запроса для повышения производительности и эффективности. BigQuery использует предварительно зафиксированные результаты из материализованных представлений и по возможности считывает только дельтативные изменения из базовой таблицы для вычисления актуальных результатов. Материализованные представления могут быть запрошены напрямую или использованы оптимизатором BigQuery для обработки запросов к базовым таблицам. Запросы, которые используют материализованные представления, обычно быстрее и потребляют меньше ресурсов, чем запросы, которые получают те же данные только из базовой таблицы. Материализованные представления полезны для значительного повышения производительности рабочих нагрузок, которые имеют характерные черты обычных и повторяющихся запросов.
Если вы уже создали материализованную таблицу в соответствии с инструкциями web.dev, вам нужно будет добавить разделы # Tony's additions 1, 2, 3 и изменить строки # Tony's modification в этом SQL-коде, чтобы итоговый отчет Looker Studio работал корректно. Если вы не используете SQL-команды из официальной документации web.dev, а строго следуете этому руководству, создайте новый запрос и добавьте в него нижеприведенный SQL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# Web Vitals Materialised Table v3.4 # https://github.com/Tiggerito/GA4-Scripts/blob/main/core-web-vitals/bigquery-materialize-table-web-vitals.sql # Replace all occurances of DatasetID with your Dataset ID CREATE OR REPLACE TABLE `${ProjectID}.${DatasetID}.web_vitals_summary` # Replace DatasetID with your Dataset ID PARTITION BY DATE(event_timestamp) CLUSTER BY metric_name AS SELECT CURRENT_TIMESTAMP() AS last_updated, 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, # Tony's additions 1 START CASE metric_rating WHEN 'good' THEN 'Good' WHEN 'ni' THEN 'Needs Improvement' WHEN 'needs-improvement' THEN 'Needs Improvement' WHEN 'poor' THEN 'Poor' ELSE metric_rating END AS metric_status # Tony's additions 1 END FROM ( SELECT ga_session_id, ARRAY_AGG(custom_event) AS events FROM ( SELECT ga_session_id, STRUCT( country, call_timestamp, call_sequence, page_timestamp, device_category, device_os, traffic_medium, traffic_name, traffic_source, page_path, # Tony's modification to support long debug_target IF(debug_target2 IS NULL, debug_target, CONCAT(debug_target, debug_target2)) AS debug_target, event_timestamp, event_date, event_name, metric_id, # Tony's modification to also support TTFB and FCP IF(event_name = 'LCP' OR event_name = 'TTFB' OR event_name = 'FCP', metric_value / 1000, metric_value) AS metric_value, user_pseudo_id, session_engaged, session_revenue, # Tony's additions 2 START metric_rating, page_location, page_type, continent, region, device_browser, effective_connection_type, save_data, width, height # Tony's additions 2 END ) AS custom_event FROM ( SELECT (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS ga_session_id, # can be null in consent mode (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id') AS metric_id, SAFE.TIMESTAMP_MILLIS(ANY_VALUE((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'call_timestamp'))) AS call_timestamp, # not sure what use this has. We also have event_timestamp ANY_VALUE((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'call_sequence')) AS call_sequence, # not sure what use this has especially when set to ANY_VALUE SAFE.TIMESTAMP_MILLIS(ANY_VALUE((SELECT CAST(COALESCE(value.double_value, value.int_value) AS INT64) FROM UNNEST(event_params) WHERE key = 'page_timestamp'))) AS page_timestamp, 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, # Tony's modification to support long debug_target values (over 100 characters) ANY_VALUE( (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'debug_target2')) AS debug_target2, 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(PARSE_DATE('%Y%m%d', event_date)) AS event_date, MAX( ( SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value' )) AS metric_value, # Tony's additions 3 START ANY_VALUE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_rating')) AS metric_rating, ANY_VALUE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location')) AS page_location, ANY_VALUE((SELECT COALESCE(value.string_value, CAST(value.int_value AS STRING)) FROM UNNEST(event_params) WHERE key = 'page_type')) AS page_type, ANY_VALUE(geo.continent) AS continent, ANY_VALUE(geo.region) AS region, ANY_VALUE(device.web_info.browser) AS device_browser, ANY_VALUE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'effective_connection_type')) AS effective_connection_type, ANY_VALUE((SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'save_data')) AS save_data, ANY_VALUE((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'width')) AS width, ANY_VALUE((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'height')) AS height # Tony's additions 3 END FROM `${ProjectID}.${DatasetID}.events_*` # Replace DatasetID with your Dataset ID WHERE # Tony's modification to support TTFB and FCP and INP event_name IN ('LCP', 'FID', 'CLS', 'TTFB', 'FCP', 'INP', 'first_visit', 'purchase') GROUP BY 1, 2 ) ) WHERE ga_session_id IS NOT NULL GROUP BY ga_session_id # can be null in consent mode ? ) CROSS JOIN UNNEST(events) AS evt WHERE evt.event_name NOT IN ('first_visit', 'purchase'); |
Вам нужно отредактировать все вхождения с ${ProjectID}.${DatasetID}, чтобы в запросе использовались ваш проект и набор данных. Таких места в SQL-запросе два - в начале и в конце.
Если вы все сделали правильно, то в правом верхнем углу вы увидите уведомление о возможном запуске этого запроса, и примерный размер запрашиваемых данных. Если нет, то проверьте свои настройки:
Нажмите кнопку RUN. После этого в вашем проекте BigQuery будет создана таблица с именем web_vitals_summary, там же, где располагается ваш экспорт данных GA4.
Сохраните запрос как Web Vitals Summary, чтобы вы могли повторно использовать его позже. Для этого нажмите SAVE - Save query:
Вы сможете найти сохраненные запросы в разделе Queries:
Создание такой материализованной таблицы не только упрощает создание отчетов, но и может сэкономить вам деньги. Как вы знаете, SQL-запросы в BigQuery стоят денег, как только вы израсходуете свой бесплатный ежемесячный лимит в 1 Терабайт (1 ТБ). Эта таблица уменьшает размер запросов, которые вы делаете в BigQuery при просмотре отчетов, делая их быстрее и дешевле.
Обновление материализованной таблицы
Этот шаг не является обязательным, его можно пропустить.
По мере регистрации новых событий Core Web Vitals вам нужно обновлять данные в вашей таблице и отчете. А для этого нужно перезапускать сам запрос. Делать это можно вручную, по мере необходимости, а можно настроить расписание.
Для этого при редактировании запроса нажмите на SCHEDULE:
Задайте расписанию запроса название (например, Web Vitals Summary) и установите нужные настройки обновления. Например, периодичность обновления раз в неделю, в понедельник, в 00:00:
Возможно, вам придется включить некоторые службы API, обновить страницу, войти в систему под своей учетной записью Gmail и вернуться к сохраненному запросу, чтобы он заработал.
После сохранения ваш запланированный запрос будет доступ в разделе Scheduled queries:
Создание копии отчета Looker Studio
Поскольку все действия, которые я выполнял в этом руководстве, были основаны на материале Core Web Vitals Tracking via GA4, BigQuery and Google Data Studio от Tony McCreath, включая SQL-запросы, то мы с легкостью можем создать итоговый отчет Looker Studio для Core Web Vitals, используя его шаблон.
Вы будете делать копию моей копии отчета Тони, поскольку нет никаких гарантий, что автор решения не удалит его когда-нибудь. Так будет спокойнее мне и вам, поскольку вы будете точно знать, что шаблон отчета по-прежнему работает и доступен для копирования. Но здесь есть нюанс - отчет Тони может со временем обновляться автором, в то время как моя копия будет всегда статична. Поэтому я приложу две ссылки, а вы уже выберете сами шаблон для копирования:
- Web Vitals v3.4 by Web Site Advantage (автор - Tony McCreath);
- Моя копия отчета.
Открыв отчет, в правом верхнем углу нажмите на иконку с тремя точками и выберите Создать копию:
После этого вам будет предложено обновить источники данных для своего отчета. Нужно обновить первый источник данных. Для этого создайте новый источник данных:
Выберите BigQuery:
Перейдите к своему проекту, набору данных и таблице. Отметьте галочкой Использовать "event_timestamp" как параметр диапазона дат. В завершение нажмите Связать и Добавить к отчету.
Другие источники подключения - это Google Таблицы, в которых отображаются различные данные о показателях Core Web Vitals (CLP, FID, CLS, INP, TTFB, TTLB, FCP) с некоторым описанием. Они нужны для визуального форматирования данных.
Остальные можно оставить как есть. Нажмите Копировать отчет. Теперь в нем будут отображаться ваши данные из материализованной таблицы BigQuery.
Вы можете отредактировать скопированный шаблон под себя, удалив все лишнее. Я рекомендую как минимум убрать из отчета следующее:
- упоминания автора и его компании (логотип, ссылки и т.д. и т.п.);
- все визуализации и дашборды, связанные с FID (First Input Delay), так как этот показатель в марте 2024 года был заменен показателем Interaction to Next Paint (INP), а окончательная его поддержка FID закончилась 9 сентября 2024 года;
- если вы не передаете в Google Analytics 4 тип страницы (page_type), тип подключения (effective_connection_type) или экономию данных (save_data), то и элементы управления, а также соответствующие визуализации в отчете вам будут не нужны.
Тем не менее, все это я оставлю и в своей копии шаблона, отдав дань разработчику отчета. Вы уже сами произведете нужные корректировки. Не забудьте переименовать отчет:
Затем вы можете опубликовать отчет и поделиться им, чтобы другие пользователи могли его видеть и использовать в работе.
По мере того, как ваш счетчик Google Analytics 4 будет собирать данные по Core Web Vitals, в вашем итоговом отчете Looker Studio их будет становиться все больше. Не забывайте только обновлять материализованную таблицу в BigQuery (если не настроили расписание), чтобы всегда иметь самые актуальную информацию по основным метрикам вашего веб-сайта.
Если кто-то из вас желает русифицировать сам отчет и поделиться им с нашим сообществом, пожалуйста, присылайте мне ссылку на шаблон Looker Studio. Я с удовольствием размещу ее в этом руководстве.
Всего в шаблоне 35 страниц. Просматривайте различные страницы отчета с помощью меню слева.
Фильтры раскрывающегося списка в верхней части влияют на весь отчет. Тони сделал их на все случаи жизни для анализа максимально возможного количества сегментов:
Чтобы классифицировать общую производительность страницы или сайта, мы используем значение 75-го процентиля всех просмотров этой страницы или сайта. Другими словами, если по крайней мере 75 процентов просмотров страниц сайта соответствуют «хорошему» порогу, сайт классифицируется как имеющий «хорошую» производительность по этому показателю. И наоборот, если по крайней мере 25 процентов просмотров страниц соответствуют «плохому» порогу, сайт классифицируется как имеющий «плохую» производительность. Так, например, LCP 75-го процентиля в 2 секунды классифицируется как «хороший», а LCP 75-го процентиля в 5 секунд классифицируется как «плохой».
В отчете Page Details URL-адреса страниц и столбцы PSI (Page Speed Insights) являются ссылками, по ним можно перейти.
В отчете содержится множество разделов, каждый из которых посвящен какой-то отдельной метрике Core Web Vitals. Например, для LCP (Largest Contentful Paint):
- LCP Status (данные по статусам LCP в разрезе типов устройств - mobile и desktop);
- LCP Score (классификация LCP по скорости загрузки страницы с секундах и статусам, значение 75-го процентиля);
- LCP Causes (данные по элементам страницы и их селекторам CSS, которые использовались в расчете);
- LCP Distribution (распределение по статусам LCP и количеству просмотров страниц);
- LCP Engagement (срез по вовлеченности пользователей и времени загрузки страниц). Этот отчет может показать, падают ли показатели вовлеченности по мере увеличения LCP. Другими словами, пользователи с большей вероятностью уйдут, если сайт работает медленно, когда LCP высокий.
Аналогичные разделы и отчеты есть в шаблоне для показателей CLP, FID, CLS, INP, TTFB, FCP.
Возможно, отчет Looker Studio изначально покажется вам избыточным и сложным. Но по мере того, как вы ближе познакомитесь с шаблоном Tony McCreath, вы сможете отредактировать его под свои задачи, добавив на листы собственные диаграммы и удалив то, что не пригодится в работе.
Итоги
Вот мы и подошли к завершению. Я вам напоминаю, что в этой публикации рассказывалось об основах использования Google Analytics 4 и BigQuery для измерения основных показателей Core Web Vitals и отладки производительности на основе данных реальных пользователей. Основная настройка велась с помощью диспетчера тегов Google. Но в руководстве я также приложил исходные коды для внедрения через тег Google (gtag.js).
Моя статья, в большей степени, была основана на материале Tony McCreath, поскольку только у этого автора был готовый шаблон Looker Studio, который можно было легко скопировать и использовать для своего источника данных BigQuery. В связи с этим мы использовали немного модифицированный код и SQL-запросы, заточенные именно под его реализацию и отчет. В статье web.dev тоже приведены пример SQL, но они чуть отличаются. И у Google не было готового отчета. Они предлагали создавать его самостоятельно. А Симо Ахава написал свое руководство еще до того, как web.dev провел презентацию по Core Web Vitals.
Так или иначе, чтобы сделать отчет в Looker Studio максимально полезным, вы можете предпринять следующие шаги:
- настройте запрос в BigQuery для получения обновленных данных по расписанию. Запрос материализации, который мы выполняли ранее, делает только слепок ваших данных на данный момент. Если вы хотите, чтобы ваш отчет Looker Studio автоматически обновлялся, вы можете запустить запланированный запрос, который будет выполняться каждый день или раз в неделю, и добавить в материализованную таблицу новые данные;
- вы можете объединить данные Google Analytics 4 с данными вашей CRM-системы для получения глубокой и детальной аналитики. Для этого в материализованной таблице нужно добавить поле user_id или user_pseudo_id отдельным столбцом (оно должно передаваться и в CRM), в зависимости от того, что вы используете. Если ваши собственные данные по клиентам из CRM еще не находятся в BigQuery, вам нужно их туда загрузить, а затем, используя SQL, объединить с текущей информацией по Core Web Vitals;
- если вы или ваши программисты постоянно проводите какие-то изменения на сайте с целью улучшения показателей Core Web Vitals, то вы можете передавать в GA4 в качестве параметра событий версию сайта, а затем добавить ее в качестве столбца в материализованной таблице. В результате вы сможете вынести эту статистику на диаграммы Looker Studio, чтобы было легче увидеть, как изменения версий сайта влияют на итоговую производительность.