Google Analytics after onLoad

update: This was written during Dojo 1.1, and is outdated. The current documentation can be found at http://docs.dojocampus.org/dojox/analytics/Urchin, as some things have changed regarding parameters and setup since this blog post.

You've all seen it, especially in the Ajax world. The page is stalled, waiting to render, the status bar woefully proclaims "waiting for google-analytics.com ... " The culprit being the ever popular urchin tracker, and the [synchronous] script tags placed
at the bottom of your webpage:

 
<script type="text/javascript">
    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
    var pageTracker = _gat._getTracker("UA-123456-7");
    pageTracker._initData();
    pageTracker._trackPageview();
</script>
 

This is usually before the body tag is closed, which causes [at least] Dojo's addOnLoad() function to wait until after ga.js has been loaded, and executed. I notice it most on the SitePen Dojo QuickStart guide. The whole guide is sent as valid HTML and CSS, then enhanced to break major sections into a custom tabbed view, with simple navigation. Unfortunately, all the code to do that is run from within an addOnLoad function, and my poor pitiful ethernets here in Tennessee make ga.js take upwards of five seconds to load. Long story short, sometimes I'm presented with a nasty jolt of rendering as the navigation is added, and the unselected chapters go hidden.

I decided it was a safe bet I could just append a script tag to my head element, and run that onLoad, allowing the rest of the code to execute as soon as the Dom was ready, regardless of Google being ready. This should work with any page that uses Dojo >= 0.9 ... I'm going to test it on this site for a while before considering making it another utility of the Toolkit. It's working so far, let's see if it picks up my traffic (the Analytics dashboard said it was getting data, but I just started it today, so I won't know until tomorrow).

This is just plain JavaScript, with some fancy scope magic for convenience. It uses Dojo because I do.

 
dojo.provide("dojox.analytics.ga");
dojo.mixin(dojox.analytics.ga, {
	// _acct: String
	//		your GA urchin tracker account numbers.
	_acct: dojo.config.urchin || "",
 
	// _loadInterval: Integer
	// 		time in ms to wait between checking again
	_loadInterval: 420,
 
	_loadGA: function(){
		// summary: load the ga.js file and begin initialization process
		var gaHost = ("https:" == document.location.protocol) ? "https://ssl." : "http://www.";
		var s = dojo.doc.createElement('script');
		s.src = gaHost + "google-analytics.com/ga.js";
		dojo.doc.getElementsByTagName("head")[0].appendChild(s);
		setTimeout(dojo.hitch(this, "_checkGA"), this._loadInterval);
	},
 
	_checkGA: function(){
		// summary: sniff the global _gat variable Google defines.
		// 		if it exists, run _gotGA, otherwise, do another interval
		setTimeout(dojo.hitch(this, window['_gat'] ? "_gotGA" : "_checkGA"), this._loadInterval);
	},
 
	_gotGA: function(){
		// summary: initialize the tracker, we've got ga.js loaded
		var ga = this._tracker = dojo.hitch(_gat, "_getTracker", this._acct)();
		ga._initData();
		ga._trackPageview();
		this.GAonLoad.apply(this, arguments);
	},
 
	GAonLoad: function(){
		// stub function to fire when urchin is complete
		// you also have access in this function to this._tracker, which is the
		// root tracker instance you called _initData() on
	}
 
}); 
 
// start it all up after body is ready:
dojo.addOnLoad(dojox.analytics.ga,"_loadGA");
 

I've hard-coded my UA-# into the code, but you would be able to define it as part of your djConfig variable, either before dojo.js is loaded:

 
<script type="text/javascript">
    var djConfig = { parseOnLoad:true, urchin:"UA-123456-7" };
</script>
 

or directly on the script tag:

 
<script src="dojo/dojo.js" djConfig="urchin: UA-123456-7, parseOnLoad:true"></script>
 

you can see the file is namespaced dojox.analytics.ga in the example. If the file were actually located there, you would be able to simply dojo.require("dojox.analytics.ga"); to include analytics tracking on any Dojo-enabled page.

update: It works! (or at least seems to.) All of yesterday's traffic apparently was tracked, and showed up in my analytics dashboard this morning.

update 2: This is now in trunk, as of revision [14006], and is known to work with 1.1 without issue. 1.0 is untested. It will be released with 1.2.

3 Comments

  1. Adding Google Analytics onLoad : Beep Interactive:

    [...] is not as quick as in the US) and that makes my page load slower. So, I went searching and found someone had done it using Dojo (via Ajaxian). I don’t use Dojo, so I have come up with an alternative way of loading it [...]

  2. Ending The ga.js Wait | Continuing Intermittent Incoherency:

    [...] thing by looking at the bottom of this page which pulls in custom.js which includes this logic. Pete Higgins blogged about how the module works when he first wrote it, and the strategy is to load Dojo from a CDN (since the page wanted it for other things) and wait [...]

  3. dojox.analytics.Urchin for jQuery | Jens Arps:

    [...] is a good idea has been discussed often enough elsewhere, so we take it as fact. Peter Higgins once wrote such a wrapper for dojo, and as of dojo 1.3, it’s officially included in dojox (see Alex Russel’s post). But [...]

Leave a comment

You must be logged in to post a comment.