竞争条件并同步使用Google Analytics异步(_gaq)

时间:2010-08-06 20:33:08

标签: google-analytics analytics race-condition

我有一个使用Google Analytics更新的异步跟踪方法(_gaq)的网站。我遇到的问题是我想建立一些特定的链接跟踪,并担心我会创造竞争条件。

基本上,它是一个新闻网站,所以它有标题链接到各地的故事。故事的标题可能出现在页面上的3个不同位置,并出现在数百个其他页面上。因此,为了理解我们的受众如何与网站进行交互,我们必须跟踪每个特定标题块的使用方式,而不仅仅是目的地。由于这两个规定跟踪单个页面,跟踪推荐页面是不够的,我们必须跟踪单个链接。

所以,如果我有一个链接。

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

由于_gaq.push()是异步调用,因此在Google完成点击跟踪之前,是否可能发生页面更改?如果是这样可以防止这种情况发生,或者我对Google Analytics异步功能的运行方式(http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html)有误解。

6 个答案:

答案 0 :(得分:11)

你是对的。如果浏览器在发送事件的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。这增加了记录事件的可能性。您可以通过延长超时来提高可能性,但这也可能会损害用户体验。这是你必须要尝试的平衡。

答案 1 :(得分:9)

我也遇到了这个问题,并决心找到真正的解决方案。

将函数推入队列怎么样?

  // 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; });

答案 2 :(得分:4)

来自Google's documentation进行通用分析(自此问题的大多数其他答案以来的新版本)。您现在可以轻松指定回调。

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来电的complete list of parameters。]

此外,我已将transport参数集添加到beacon(实际上并不需要,因为如果合适,它会自动设置):

  

这指定了将发送命中的传输机制。   选项是'beacon','xhr'或'image'。默认情况下,analytics.js   将尝试找出基于命中大小的最佳方法   浏览器功能。如果指定'beacon'和用户的浏览器   不支持navigator.sendBeacon方法,它会退回   根据命中大小来'成像'或'xhr'。

因此,当使用navigator.beacon时,导航不会中断跟踪。不幸的是,微软支持信标is non existent,所以你仍然应该将重定向放在回调中。

答案 3 :(得分:2)

在事件处理程序中,您应该设置命中回调:

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

发送数据

_gaq.push(['_trackEvent'

并停止事件事件处理

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

答案 4 :(得分:1)

我正在尝试一种新的方法,我们自己构建utm.gif的URL,并请求它,然后只有在我们收到响应(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;
}

答案 5 :(得分:0)

使用onmousedown而不是onclick也可能有所帮助。它并没有消除竞争条件,但它给了GA一个良好的开端。还有人担心有人点击链接并在放开鼠标按钮之前拖走,但这可能是一个可以忽略不计的情况。