【问题标题】:Race condition and using Google Analytics Asynchronous (_gaq) synchronously竞争条件和同步使用 Google Analytics 异步 (_gaq)
【发布时间】:2011-03-26 13:11:06
【问题描述】:

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

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

如果我有链接。

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

因为 _gaq.push() 是异步调用,是不是可能在 Google 完成点击跟踪之前就发生了页面变化?如果是这样,有没有办法防止这种情况发生,或者我对 Google Analytics Async 的运行方式有误解 (http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html)。

【问题讨论】:

标签: google-analytics analytics race-condition


【解决方案1】:

来自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)
            });

[这里有一个complete list of parameters,用于所有可能的ga 调用。]

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

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

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

【讨论】:

  • 不错,这就是我一直在寻找的答案。
【解决方案2】:

在事件处理程序中你应该设置点击回调:

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

给你发送数据

_gaq.push(['_trackEvent'

并停止事件事件处理

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

【讨论】:

    【解决方案3】:

    使用 onmousedown 代替 onclick 也可能有帮助。它并没有消除竞争条件,但它为 GA 提供了一个良好的开端。还有人担心在松开鼠标按钮之前单击链接并拖走,但这可能是微不足道的情况。

    【讨论】:

      【解决方案4】:

      我正在尝试一种新方法,我们自己构建 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】:

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

      将函数推入队列怎么样?

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

      【讨论】:

      • 另一种想法:手动创建 utm.gif URL,将其插入 DOM,绑定其加载事件,等待图像加载,然后发送用户。
      • 嗯,我查看了 ga.js 的源代码,似乎当函数被推送到 _gaq 时,它们会立即被执行? code.google.com/apis/analytics/docs/tracking/…
      • 所以我认为将你的函数推入 _gaq 的价值在于,如果 ga.js 尚未加载,那么 document.location 调用将不会被执行,直到它被执行。
      • 有人知道这是否有效吗?我可以像这样在锚中使用该代码 sn-p 吗? &lt;a href="http://whatever" onclick="code(); return false;"&gt;
      • Alex - 实际上,我认为这是可行的。推送到队列中的函数是同步执行的。尽管_trackEvent 方法本身是异步的,但重要的是触发XHR 请求。所以第二个函数的执行应该被阻止直到_trackEvent被执行,不是吗?
      【解决方案6】:

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

      【讨论】:

      • 不。该检查的目的是确定 GA 是否已加载。如果您使用异步语法,检查 _gaq 不会告诉您任何信息;你在你的 sn-p 代码中创建它。使用异步时,_gat 仅在 ga.js 执行时创建,因此检查它会告诉您是否会立即发送跟踪信标。
      • 理论上,我可以将超时设置为一个相当低的数字,例如 100 毫秒。虽然不完美,但每毫秒的延迟都意味着会记录更多的点击次数,并且在比赛中丢失的次数会更少。除非有办法让 _gaq.push() 返回一个值,然后等待该值,否则似乎确实没有一个理想的解决方案。
      • 这与 _gaq.push 或异步没有任何关系。同样的情况也适用于旧的 GA 语法,因为 GA 不支持跟踪信标上的回调。我真希望他们能适应这种情况。
      • Google 对此有一个文档:support.google.com/analytics/bin/…
      猜你喜欢
      • 2010-11-27
      • 2021-06-04
      • 1970-01-01
      • 2018-08-21
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      相关资源
      最近更新 更多