АБ тесты с Google Optimize на серверной стороне

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

Вариант Б в клиентском тесте

Тем не менее, у сторонних сервисов часто бывают шире возможности по сегментации трафика, они позволяют быстро тестировать мелкие изменения, которые вполне можно реализовать на клиенте, и самое главное - они экономят время аналитика на адхоки с текущим срезом. То есть, за нами остаётся выбор варианта на сервере там, где это важно. Теперь разберем серверную реализацию в Google Optimize.

Тонкости настройки аналитики в Telegram канале

Содержание

  1. Как устроены АБ тесты в Google Optimize
  2. Как сделать эксперимент на серверной стороне
  3. Как передать данные в Google Analytics
  4. Ответы на вопросы
  5. Данные АБ тестов в Bigquery
  6. Полезные ссылки
  7. Комментарии

Как устроены АБ тесты в Google Optimize

Optimize в основе использует проверенную систему из Google Analytics. Для каждого сеанса участника передаются параметры с идентификатором эксперимента и номером варианта. Причем эту информацию достаточно отправить один раз, далее она приклеится к clientId и будет сопровождать его, пока эксперимент не остановят.

Как завести там эксперимент, подробно описано в доке. Потыкайте че-нибудь, лишь бы получить идентификатор эксперимента, он выглядит примерно так:

QdJh06NITaWQ6N9RNR3N1g

Нумерация вариантов начинается с 0 и соответствуют порядку, указанному в настройках эксперимента.

Нумерация вариантов в Optimize

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

Как сделать эксперимент на серверной стороне

Естественно, не обойтись без доработки на бэкэнде, но алгоритм простой, не волнуйтесь и держите меня за ✋

  • проверяем 🍪
  • выбираем вариант
  • отдаем контент для выбранного варианта на клиент вместе с записью в 🍪

Как передать данные в Google Analytics

Теперь, чтобы магия случилась, нужно передать инфу в аналитикс. Бэкэнд разработчик еще не успел далеко уйти, так что просим they/them вместе с выбранным вариантом контента отправлять на клиент примерно такой код:

window.dataLayer = window.dataLayer || []
window.dataLayer.push({
  event: 'testAB',
  details: {
    // идентификатор эксперимента из Optimize или внутренний
    expId: 'QdJh06NITaWQ6N9RNR3N1g',
    // номер варианта
    expVar: '0',
  },
})

На данном этапе необязательно указывать значение expId именно из оптимайза, можно любое, лишь бы до поры до времени уникальное.

В Tag Manager понадобится триггер, реагирующий на Пользовательское событие testAB, и тег, который осуществит передачу.

Тег для передачи события теста в GA

О зелененьком подробнее:

  • expId и expVar - поля счетчика, в которые нужно передать всю инфу об эксперименте

  • {{DL - details.expId}} - идентификатор эксперимента из dataLayer

  • {{DL - details.expVar}} - номер варианта из dataLayer

  • {{AB_NAMES}} - таблица поиска, которая превращает бездушный номер эксперимента во что-то понятное и незабываемое.

Для умненьких аналитиков рекомендую завести еще {{AB_IDS}}, которая будет отражать соответствие вашей внутренней нумерации тестов идентификаторам из Оптимайза. Это удобно, потому что какой-нибудь 42 в разговоре маглам проще осознать, чем набор 6ук30цифр, и потому что иногда тесты приходится заводить заново 😊.

Ответы на вопросы

  • Нет, не надо плодить хиты. Достаточно отправить инфу о тесте в аналитикс один раз. Например, отдать код с dataLayer на клиент только при первичной простановке куки с вариантом.
  • Да, мы так и не поставили контейнер оптимайза на сайт, это необязательно.
  • Да, никакие предпросмотры вариантов не работают, с чего бы.
  • Да, в активных юзерах пусто, и это нормально.
  • Да, оптимайз будет ждать конверсию юзера и в этом сеансе, и в следующем, и еще у их внуков.
  • Да, экспериментальные сеансы продолжатся, даже если перестать отправлять данные в GA.

Остановленный АБ тест

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

Данные АБ тестов в Bigquery

Для изучающих BQ вот пример запроса, которым можно получить общие данные по эксперименту.

with dates as (
  select
    '20190901' as first
  , '20190915' as last
),
exp as (
  select
    experiment.experimentVariant as v
  , count(distinct fullVisitorId) as u
  from
    `project.property.ga_sessions_*`
  , dates
  , unnest(hits) hits
  , unnest(hits.experiment) experiment
  where _table_suffix between dates.first and dates.last
  and experiment.experimentId = 'QdJh06NITaWQ6N9RNR3N1g'
  --and regexp_contains(hits.page.pagePath, r'/фильтр/по/странице')
  group by 1
),
conv as (
  select
    experiment.experimentVariant as v
  , count(distinct fullVisitorId) as u
  from
    `project.property.ga_sessions_*`
  , dates
  , unnest(hits) hits
  , unnest(hits.experiment) experiment
  where _table_suffix between dates.first and dates.last
  and experiment.experimentId = 'QdJh06NITaWQ6N9RNR3N1g'
  --and regexp_contains(hits.page.pagePath, r'/фильтр/по/странице')
  and hits.eventInfo.eventCategory = 'конверсионное'
  and hits.eventInfo.eventAction = 'событие'
  group by 1
),
pivot as (
  select
    exp.v as variant
  , exp.u as all_participants
  , conv.u as converted
  , replace(cast(round(conv.u/exp.u * 100, 2) as string), '.', ',') as conversion
  from exp
  left join conv
  on exp.v = conv.v
)
select *
from pivot
order by 1 asc

Полезные ссылки

  1. Документация Google Optimize
  2. Как оптимайз считает результаты
  3. Как читать отчеты оптимайза
  4. Поля analytics.js ля эспериментов
  5. Схема экспорта GA в Bigquery