27 December 2011

Анализ использования SPA-приложения при помощи Google Analytics

Web analytics
В этом топике я хочу описать свой опыт про прикручиванию Google Analytics к web-приложению, построенному по принципу Single-page application.
До выполнения этой задачи я очень отдаленно представлял, что такое Google Analytics и с чем его едят. По этой причине также хочу рассказать и о том, как я понял Google Analytics, убив на это много часов времени. Надеюсь, эта выжимка поможет тем, кто начинает знакомиться с этой системой аналитики.
Сама по себе задача также немного нестандартная, и полученный опыт «скрещивания ежа с ужом» может быть кому-нибудь полезным.
Итак,

Цель анализа


Приложение, использование которого анализировалось, является приложением SaaS для совместной работы и управления проектами. Приложение имеет следующую схему регистрации — создать аккаунт можно одним кликом с главного сайта, а затем этот аккаунт уже можно зарегистрировать, дав ему URL и указав данные для входа в систему. Такая схема была придумана, чтобы потенциальные клиенты могли ознакомиться с системой, не вводя никаких данных — т.е. мы не гнушаемся лентяями и параноиками в качестве клиентов.
Понятно, что такой однокликовый аккаунт (мы его называем анонимным) имеет свои ограничения, самым существенным из которых является отсутствие выделенного URL (идентификация осуществляется при помощи cookies). Как следствие, в таком аккаунте может работать только один пользователь, и хотя других создавать можно, войти в систему они не смогут.
Если кто-то хочет ознакомиться с системой плотнее, ему предлагается зарегистрировать аккаунт. При регистрации указывается URL и e-mail с паролем для входа в систему. Также предлагается выбрать предполагаемый тарифный план или бесплатный однопользовательский план.
Задача состояла в том, чтобы выяснить причины ухода людей с анонимных аккаунтов без регистрации. Эти данные предполагается использовать для улучшения процента регистраций.

Почему именно Google Analytics


Сразу оговорюсь — при решении этой задачи предполагалось использовать «неинвазивные» методы диагностики, т.е. всякие опросники по выходу из системы были исключены.
Поскольку у нас не было опыта решения таких задач, то первая идея, которая пришла в голову — каким-то образом фиксировать работу пользователей (в идеальном варианте — записывать видео). По этой записи можно попытаться понять, что пользователи делают и почему не регистрируются.
Гугл показал нам на Clicktale. По описанию все выглядит очень красиво: вставляется некий javascript-код, и все действия пользователей начинают записываться — перемещения мыши, клики, ввод с клавиатуры.
Система позволяет строить heatmap-ы (карты интенсивности распределения кликов или движений мыши по страницам — усредненные показатели по куче пользователей), строить много всяких статистических графиков, а главное — воспроизводить видео конкретных посещений!
Но при ближайшем рассмотрении оказалось, что не все так гладко. Система работает следующим образом — записываются координаты перемещений и кликов, и события нажатий на клавиатуре. Затем в IFRAME открывается наш сайт и записанные события воспроизводятся. Однако, при этом принципиально не поддерживается AjAX в общем виде, хотя справедливости ради нужно сказать, что ребята над этим работают и выпускают плагины для типовых AJAX-реализаций.
Иными словами, система хорошо подходит для статичных сайтов. Чтобы ее прикрутить к web-приложению, тем более SPA, нужно много времени и напильников.
Посмотрели в сторону коммерческих систем аналитики — Totango, mixpanel, но они (логично) оказались заточены именно под аналитику сайтов — вычисление всяких рейтов и эффективностей, но не анализ использования приложений.
Были даже шальные мысли «наваять что-то свое», однако увидели интересную онлайн-утилиту визуализации путей пользователей GAVisual, вытягивающую данные из Google Analytics, и поняли, что в таком виде неплохо бы данные и видеть. Пусть это не видео работы пользователей, но по крайней мере последовательность действий и место ухода видно четко. При этом не надо вручную перелопачивать десятки и сотни сессий. В дальнейшем похожая фича появилась в самом интерфейсе Google Analytics под названием «Поток посетителей» (Visitors Flow).
И, наверное, решающим фактором стало то, что Google Analytics была уже прикручена к приложению.

Общие необходимые принципы Google Analytics


Здесь, ни на что не претендуя, я постараюсь рассказать о том, как я понял Google Analytics применительно к нашей задаче. Говорю «применительно» потому, что изначальная сфера использования Google Analytics — получение статистической информации о посещениях сайта и «эффективности различных маркетинговых мероприятий» (цитата). Иными словами, анализ поведения пользователей на сайте как цель использования Google Analytics не рассматривается, а является лишь следствием универсальности платформы. Далее, система заточена в первую очередь для сайтов, а не для приложений. Ниже я подробнее расскажу о том, какие грабли из этого получились и как мы на них наступали, но пока о самой системе Google Analytics.
Для желающих более подробно разобраться с аналитикой вообще и Google Analytics есть масса материалов, например, отличные статьи в начале блога по web-аналитике.

По понятиям:


Хит (прошу не придираться к названию) — одиночный запрос клиентского браузера с загруженным сайтом/приложением к серверу статистики. Хиты бывают (в основном) двух типов — PageView и Event. Первый означает, что клиент открыл некую страницу, второй — что произошло некое событие, не связанное с открытием страницы.
В примерах про Event часто используется «началось воспроизведение видео», но это может быть абсолютно все — перемещение мышки, клики, ввод с клавиатуры, даже события по таймеру.
Единственный способ вызвать event — напрямую обратиться к GA при помощи API, в то время как для отслеживания PageView достаточно просто присутствия кода GA на странице (он сам посылает хит после загрузки страницы).

Интересно, что в GA хит выполняется GET-запросом к GIF-файлу, хотя может казаться логичным сделать запрос к web-сервису. Насколько я знаю, так сделано ради уменьшения трафика. Также сказывается и то, что от сервера никаких данных получать не надо. Хит передает множество информации — ID посетителя и сессии, URL открываемой страницы, название Event-а, разрешение экрана и пр.

Visitor (Посетитель) — уникальный клиент, зашедший на сайт. Определяется при помощи cookies.

Visit (Посещение) — последовательность действий (=хитов) некого клиента. Заканчивается по закрытию браузера или истечению 30-минутного периода неактивности. Отслеживается также при помощи cookies. Мне, как программисту, проще называть это «сессией».

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

Account (Аккаунт) — привязанное к google-аккаунту хранилище хитов. В одном google-аккаунте может быть несколько аккаунтов аналитики. Различные аккаунты, даже в пределах одного google-аккаунта, полностью изолированы друг от друга. В пределах аккаунта указываются пользователи, имеющие к нему доступ, фильтры, которые можно будет применять к данным (но которые еще не применяются), и некоторые другие настройки.

Web property (Веб-ресурс) — Верхний уровень аккумуляции данных в Google Analytics. Каждый ресурс имеет свой уникальный код, который вписывается в клиентский скрипт и шлется в дальнейшем вместе с каждым хитом.

Profile (Профиль) — подмножество данных в пределах одного ресурса. Каждый ресурс имеет минимум один профиль; в профилях можно указывать фильтры, по которым отбираются данные. Важно, что профили строятся не динамически по данным ресурса. Например, если создать новый профиль, то собранные до создания профиля данные в нем не появятся.
Профиль — основная «рабочая единица». Вся статистика вычисляется и все отчеты строятся в пределах одного профиля.


Advanced segment (Расширенный сегмент) — подмножество данных в пределах профиля, определяемое фильтрами. В отличие от профилей, сегменты строятся сразу по всем данным профиля. Также данные различных сегментов можно сравнивать между собой (данные разных профилей — нельзя).
Обидно, что в сегментах можно фильтровать не по всем полям. Так, мы хотели отфутболить тестовый трафик из офиса, портящий статистику. Пришлось делать это через профиль, и как следствие, собранные ранее данные «вычистить» не удалось.

На основании собранных данных вычисляются различные показатели — количество посетителей в день/месяц/..., количество посещений в день/месяц/..., соотношение новых и вернувшихся посетителей, среднее время просмотра страницы/пребывания на сайте, процент завершения сессии на конкретной странице и много-много других.
В таком виде статистика мало полезна, т.к. она ничего не знает о наших целях. Цели в Google Analytics могут указываться как страница, до которой нужно добраться, как минимальное время, проведенное на сайте, количество открытых страниц за посещение или же фиксированное событие. Есть еще «группы каналов», позволяющие отслеживать последовательности действий, но это уже высший пилотаж.
Главный вывод, который я сделал — аналитика эта хороша, когда точно знаешь, что от нее хочешь :) Мы же такого понимания не имели, поэтому решили просто смотреть, что делают посетители в приложении при помощи отчета «Visitors flow (Поток посетителей)». Ну и обращаться к базовой статистике, если вдруг поймем, как ее интерпретировать.

Как это делалось


Самая первая проблема, с которой мы столкнулись, заключалась в следующем. Основная «единица» анализа в Google Analytics — страница сайта. Естественно, у нас в приложении как таковых страниц нет.
К счастью, в приложении достаточно просто удалось выделить аналог страницы. Не знаю, как дать этому нормальное определение, но в большинстве случаев это был либо список объектов конкретного типа в конкретном виде, либо экран с детальной информацией о том или ином объекте. Я подозреваю, что что-то подобное можно выделить в любом приложении.
К еще большему счастью, страницам нашлось однозначное соответствие в клиентской архитектуре приложения. Отслеживание открытия страниц было лишь делом техники — нужный код с обращением к API GA в нужном месте (единственном!), и все готово. Так и было сделано когда-то давно.
Тут следует сделать отступление. Изначально статистика прикручивалась «на всякий случай», без всяких конкретных целей. И первые же грабли, на которые мы наступили, были в том, что меню и сайдбар в системе строились на основе того же объекта, что и страницы. То есть, при загрузке системы код аналитики честно слал три хита — помимо основной страницы «открывались» еще меню и сайдбар. До Гугла они доходили наперегонки — можете представить, как это выглядело в Visitors flow:


Помимо каши в начале посещений мы получили почти нулевой процент отказов. Отказом считается посещение только одной страницы в сессии, а у нас их «открывалось» сразу три.
Убрать паразитные вызовы из кода труда не составило, хотя месяцы ранее собранной статистики они не вернули.

Затем выяснилось, что приложение слало хиты почти при каждом клике пользователя. И эти хиты были типа Event. Логично, не PageView же слать. Несмотря на то, что Event-ы были более-менее структурированы (есть три уровня иерархии: категория, действие и метка), все Event-ы смешались, и сделать какие-либо осмысленные выводы мы не смогли.
Самая большая проблема заключается в том, что event-ы не фиксируются в Visitors Flow, т.е. последовательность событий восстановить не получается.
Event-ы были добросовестно вычищены из приложения, оставили только минимум необходимых для ведения статистики регистраций.

На третье вместо компота получили самую большую проблему — посетители не были сегментированы. Возвращаясь к целям — нам нужно отслеживать поведение новичков, которые только создали анонимный аккаунт. Google Analytics, естественно, ничего не знал о источниках хитов, и в одну кучу свалил и новичков, и бывалых, и даже тех, кто уже купил. Толку с этой кучи нам никакого не было.
На помощь пришли пользовательские переменные. Если говорить примитивно, то к хиту можно привязать до 5 пар «имя-значение», по которым потом фильтровать данные в Advanced segments. В код аналитики была добавлена строка, устанавливающая значение переменной в тип аккаунта (анонимный, триальный или купленный), и настроен Advanced Segment. Помимо триальных и купленных аккаунтов, были отброшены также «возвращенцы»:

С большего к этому моменту все было готово для сбора статистики. Но наш специалист по UX выдвинул еще одно требование — поведение пользователей на странице регистрации должно отслеживаться детально. От отслеживания перемещений мыши слава Богу отказались (сессия в аналитике не резиновая — максимум вроде 500 хитов), но фокусы на полях, клики по кнопкам и ввод с клавиатуры отслеживать было нужно.
События для этого не годились — нужно было восстанавливать последовательность действий. Мы решили вместо событий использовать PageView (да простят нас создатели Google Analytics). То есть, фокус в поле ввода e-mail — как будто открытие страницы /register/emailfocus, ввод с клавиатуры в поле пароля — страница /register/passwordkeypress и т.п.
Технически реализовать подобное оказалось несложно — клиентский API позволят имитировать открытия страниц, указывая URL страницы. Более того, оказалось что аналитика группирует одинаковые открытия, идущие подряд, считая их за одно открытие. Это оказалось полезно при отслеживании ввода с клавиатуры.
Последним требованием было фиксировать причину неуспешной регистрации (незаполненные поля, занятый URL и т.п). Тут сделали совсем просто — к URL-у виртуальной страницы, «открываемой» при неуспешной регистрации, добавили текст Validation summary. Получили «открытия» страниц вида register/submitinvalid/aliasistaken.
После запуска кода и получения первой статистики нас ждало разочарование. Отдельно разочаровывало упущенное время — данные в Analytics появляются с задержкой в несколько часов, поэтому обычно результат изменений виден только на следующий день.
Собственно же разочарование заключалось в том, что путь до страницы регистрации и на самой странице фиксировался как различные посещения. Причина этого заключалась в реализации страницы регистрации — она была в отдельном приложении, отображаемом в IFRAME (причины этого не технические, а организационные — так было проще разделить работу). IFRAME отображал URL в другом поддомене, и аналитические cookies, соответственно, в поддомен не пролазили.
У Гугла уже есть готовое решение для данной ситуации. Отмечу только, что _setAllowHash не делали, поскольку шарить куки между основным доменом и поддоменами не требовалось — только между поддоменами.
С целью экономии времени на дебаг использовали фичу Real-time, которая пока в beta-стадии. Тем не менее, она работает :) Для дебага завели отдельный ресурс в аккаунте, и результат изменений стало видно сразу:


Не считая мелочей, это всё.

Осталась одна проблема, которую пока не побороли. В Visitors flow упорно фиксируются посещения корневой страницы, хотя хиты PageView с пустым URL не происходят. Скорее всего это так регистрируются Event по регистрации аккаунта. Event тоже относится к некоторой странице, а поскольку у нас SPA, то все Events автоматически относятся к корневой странице. Способа принудительно прописать страницу у Event-а через клиентский API мы не нашли.
Более странным выглядит уход пользователей с этой корневой страницы — т.е. как будто событие о регистрации аккаунта пришло, а PageView начальной страницы — нет. Можно конечно допускать, что пользователь быстро закрывает браузер в нужный момент, но процент таких выходов достаточно большой. Не думаю, что у многих пользователей такая хорошая реакция и интуиция (нужно ведь угадать момент). Детально проблему пока не исследовали — жить она не сильно мешает.
Еще из замеченного — данные в отчет Visitors flow попадают чуть позже, чем в остальные отчеты, поэтому количество посещений в этом отчете чуть меньше, чем в других.
Также иногда анноит в этом отчете загадочная группировка страниц — на некотором шаге итерации может быть одна группа, в которой, допустим, 8 страниц. Почему эти страницы не показываются отдельно (место-то на экране есть) — одному Гуглу известно.
В итоге получили примерно следующее:

Интерпретация этого — тема для отдельной статьи, и может не для одной.
Tags:web 2.0google analyticsвеб аналитика
Hubs: Web analytics
+14
4.1k 47
Comments 10
Top of the last 24 hours