Race Status and Synchronous Use of Asynchronous (_gaq) Google Analytics

I have a website that uses the Google Analytics asynchronous tracking method (_gaq). The problem I am facing is that I want to set up some specific link tracking and worry that I will create race conditions.

Basically, this is a news site, so it has headlines that link to stories everywhere. The title for the story can be displayed in three different places on the page and displayed on hundreds of other pages. Thus, in order to understand how our audience interacts with the site, we must track how each specific block of the header is used, and not just the destination. Due to these two provisions, tracking individual pages, as well as tracking the mentioned pages will not be enough, we must track individual links.

So, if I have a link.

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

Since _gaq.push () is an asynchronous call, is it possible for the page to change before Google click tracking is complete? If there is a way to prevent this, or I have a misunderstanding about how the Google Analytics Async function works ( http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html ).

+18
race-condition analytics google-analytics
Aug 6 '10 at 20:33
source share
6 answers

You're right. If the browser leaves the page before sending the GA tracking beacon (gif hit) for the event, the event will not be recorded. However, this is not new to asynchronous code, since the process of sending a tracking beacon is asynchronous; old code worked the same way in this regard. If tracking is really important, you can do something like this:

 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> 

This will cause the browser to not go to the next page when the link is clicked if GA is already loaded (it is probably best to prevent the user from waiting so long). Then it sends an event and waits 200 milliseconds to send the user to the href of the link they clicked on. This increases the likelihood that the event will be recorded. You can increase the likelihood of even more by increasing the waiting time, but it can also damage the user experience in the process. This is the balance with which you will have to experiment.

+11
Aug 07 '10 at 5:08
source share

I also have this problem, and I decided to find a real solution.

How about pushing a function into a queue?

  // 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; }); 
+9
Mar 09 '11 at 18:31
source share

From the Google documentation for universal analytics (new version, as most other answers to this question). Now you can easily specify a callback.

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

For clarity, I would recommend using this syntax, which allows you to specify which properties you are sending, and it’s easier to add more:

  ga('send', 'event', { 'eventCategory': 'Homepage', 'eventAction': 'Video Play', 'eventLabel': label, 'eventValue': null, 'hitCallback': function() { // redirect here }, 'transport': 'beacon', 'nonInteraction': (interactive || true ? 0 : 1) }); 

[Here is a complete list of parameters for all possible ga calls.]

In addition, I added the transport parameter to the beacon value (actually not needed, because it is automatically set if necessary):

Specifies the transport mechanism with which hits will be sent. The options are: beacon, xxr, or image. By default, analytics.js will try to figure out the best method based on the size of the hits and the browser. If you specify "beacon" and the user browser does not support the navigator.sendBeacon method, it will drop to 'image' or 'xhr' depending on the size of the strokes.

Therefore, when using navigator.beacon navigation does not interrupt tracking. Unfortunately, Microsoft beacon support does not exist , so you have to put the redirect in a callback.

+4
Sep 22 '15 at 9:04 on
source share

In the event handler, you must configure the callback:

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

send data

 _gaq.push(['_trackEvent' 

and stop processing the event event

 e.preventDefault(); e.stopPropagation(); 
+2
Mar 28 '14 at 9:34
source share

I try to use a new approach, when we create the URL for utm.gif on our own and request it, then only after we get the response (gif), we send the user along the path:

Using:

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

Code (CrumbleCookie from: 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; } 
+1
Mar 09 2018-11-11T00:
source share

Using onmousedown instead of onclick can also help. This does not eliminate the race condition, but gives GA a start. There is also concern that someone clicks on the link and drags it out before releasing the mouse button, but this is probably an insignificant case.

0
Mar 10 2018-11-11T00:
source share



All Articles