Состояние гонки и синхронное использование асинхронной (_gaq) Google Analytics

У меня есть сайт, на котором используется асинхронный метод отслеживания Google Analytics (_gaq). Проблема, с которой я столкнулся, заключается в том, что я хочу установить какое-то конкретное отслеживание ссылок и беспокоюсь, что я буду создавать условия гонки.

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

Итак, если у меня есть ссылка.

<a href="#" onclick="location.href='http://www.blah.com'; return false;" onclick="_gaq.push('_trackEvent','stuff')">Here</a>

Поскольку _gaq.push() является асинхронным вызовом, возможно ли, что изменение страницы произойдет до завершения Google отслеживания кликов? Если есть способ предотвратить это, или у меня есть недоразумение о том, как работает функция Google Analytics Async (http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html).

Ответ 1

Ты прав. Если браузер покидает страницу, прежде чем отправит маяк отслеживания GA (gif-хит) для события, событие не будет записано. Однако это не ново для асинхронного кода, поскольку процесс отправки маяка отслеживания является асинхронным; старый код работал одинаково в этом отношении. Если отслеживание действительно важно, вы можете сделать что-то вроде этого:

function track(link) {
  if (!_gat) return true;
  _gaq.push(['_trackEvent', 'stuff']);
  setTimeout(function() {location.href=link.href'}, 200);
  return false;
}

...

<a href="example.com" onclick="return track(this);"></a>

Это приведет к тому, что браузер не перейдет на следующую страницу при щелчке ссылки, если GA уже загружен (вероятно, лучше не допустить, чтобы пользователь так долго ждал). Затем он отправляет событие и ждет 200 миллисекунд, чтобы отправить пользователя на href ссылки, на которую они нажали. Это увеличивает вероятность того, что событие будет записано. Вы можете увеличить вероятность еще большего, увеличив время ожидания, но это также может нанести ущерб пользовательскому опыту в этом процессе. Это баланс, с которым вам придется экспериментировать.

Ответ 2

У меня тоже есть эта проблема, и я решил найти реальное решение.

Как насчет нажатия функции в очередь?

  // Log a pageview to GA for a conversion
  _gaq.push(['_trackPageview', url]);
  // Push the redirect to make sure it happens AFTER we track the pageview
  _gaq.push(function() { document.location = url; });

Ответ 3

Из документация Google для универсальной аналитики (новая версия, так как большинство других ответов на этот вопрос). Теперь вы можете легко указать обратный вызов.

var trackOutboundLink = function(url) {
   ga('send', 'event', 'outbound', 'click', url, {'hitCallback':
     function () {
     document.location = url;
     }
   });
}

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

            ga('send', 'event', {
                'eventCategory': 'Homepage',
                'eventAction': 'Video Play',
                'eventLabel': label,
                'eventValue': null,

                'hitCallback': function()
                {
                    // redirect here
                },

                'transport': 'beacon',

                'nonInteraction': (interactive || true ? 0 : 1)
            });

[Здесь полный список параметров для всех возможных вызовов ga.]

Кроме того, я добавил параметр transport в значение beacon (фактически не нужен, потому что он автоматически устанавливается, если необходимо):

Указывает транспортный механизм, с которым будут отправляться хиты. Возможные варианты: "маяк", "ххр" или "изображение". По умолчанию analytics.js будет пытаться выяснить лучший метод, основанный на размере ударов и браузера. Если вы укажете "beacon" и пользовательский браузер не поддерживает метод navigator.sendBeacon, он отпадет to 'image' или 'xhr' в зависимости от размера ударов.

Поэтому при использовании navigator.beacon навигация не прерывает отслеживание. К сожалению, поддержка Microsoft beacon не существует, поэтому вы должны поместить перенаправление в обратный вызов.

Ответ 4

В обработчике событий вы должны настроить ответный вызов:

_gaq.push(['_set', 'hitCallback', function(){
  document.location = ...
}]);

отправить данные

_gaq.push(['_trackEvent'

и прекратить обработку события события

e.preventDefault();
e.stopPropagation();

Ответ 5

Я пытаюсь использовать новый подход, когда мы создаем URL-адрес для utm.gif самостоятельно и запрашиваем его, тогда только после того, как мы получили ответ (gif), мы отправляем пользователя по пути:

Использование:

  trackPageview(url, function() { document.location = url; });

Код (CrumbleCookie от: http://www.dannytalk.com/read-google-analytics-cookie-script/)

/** 
 * Use this to log a pageview to google and make sure it gets through
 * See: http://www.google.com/support/forum/p/Google%20Analytics/thread?tid=5f11a529100f1d47&hl=en 
 */
function trackPageview(url, fn) {
  var utmaCookie = crumbleCookie('__utma');
  var utmzCookie = crumbleCookie('__utmz');

  var cookies = '__utma=' + utmaCookie + ';__utmz=' + utmzCookie;

  var requestId = '' + (Math.floor((9999999999-999999999)*Math.random()) + 1000000000);
  var hId = '' + (Math.floor((9999999999-999999999)*Math.random()) + 1000000000);

  var utmUrl = 'http://www.google-analytics.com/__utm.gif';
  utmUrl += '?utmwv=4.8.9';
  utmUrl += '&utmn=' + requestId;
  utmUrl += '&utmhn=' + encodeURIComponent(window.location.hostname);
  utmUrl += '&utmhid=' + hId;
  utmUrl += '&utmr=-';
  utmUrl += '&utmp=' + encodeURIComponent(url);
  utmUrl += '&utmac=' + encodeURIComponent(_gaProfileId); 
  utmUrl += '&utmcc=' + encodeURIComponent(cookies);

  var image = new Image();
  image.onload = function() { fn(); };
  image.src = utmUrl;
}

/**
 *  @author:    Danny Ng (http://www.dannytalk.com/read-google-analytics-cookie-script/)
 *  @modified:  19/08/10
 *  @notes:     Free to use and distribute without altering this comment. Would appreciate a link back :)
 */

// Strip leading and trailing white-space
String.prototype.trim = function() { return this.replace(/^\s*|\s*$/g, ''); }

// Check if string is empty
String.prototype.empty = function() {
    if (this.length == 0)
        return true;
    else if (this.length > 0)
        return /^\s*$/.test(this);
}

// Breaks cookie into an object of keypair cookie values
function crumbleCookie(c)
{
    var cookie_array = document.cookie.split(';');
    var keyvaluepair = {};
    for (var cookie = 0; cookie < cookie_array.length; cookie++)
        {
        var key = cookie_array[cookie].substring(0, cookie_array[cookie].indexOf('=')).trim();
        var value = cookie_array[cookie].substring(cookie_array[cookie].indexOf('=')+1, cookie_array[cookie].length).trim();
        keyvaluepair[key] = value;
    }

    if (c)
        return keyvaluepair[c] ? keyvaluepair[c] : null;

    return keyvaluepair;
}

Ответ 6

Использование onmousedown вместо onclick также может помочь. Это не устраняет состояние гонки, но дает GA начало. Там также забота о том, чтобы кто-то нажал на ссылку и утащил ее, прежде чем отпустить кнопку мыши, но это, вероятно, незначительный случай.