Non-Blocking Google Analytics Integration

Google Analytics has become the default web-analytics provider being a powerful, free, and easy to use service offered by a well-known reputable company. Aside from being pretty great; using Google Analytics on your website/webapp still means it is third-party integration. Third-party integrations tend lack control on the side of the client or user, Google Analytics is no exception here.

I’ve developed a method of integrating Google Analytics which allows the user/client to regain control over the loading and execution while not blocking other JavaScript code on the page from executing. This method requires either YUI or jQuery to be present but can be adapted to work with other JavaScript libraries.

Standard Integration (and potential issues with it)

Google has a recommended integration of Google Analytics into your website/webapp. It requires a website owner or web developer to copy and paste a couple of script blocks with a few lines of JavaScript at the bottom of every web page (or at the bottom of their website/webapp template).

“By placing the script at the end of the page body, you ensure that the tracking code is executed as the last element of the DOM.”

- Tracking Code and Page Load

Code for Standard Integration

<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-xxxxxx-x");
pageTracker._trackPageview();
</script>

Issues With Standard Integration

Google is correct here; the analytics code will be executed as the last element of the DOM, and therefore before onDOMReady. This means that any of your JavaScript code that is waiting for the DOM to be ready before it executes will also be waiting for Google Analytics to load and execute. Web pages depend more on JavaScript to make them interactive and functional; making it important to not block browsers from considering the DOM to be ready, and allowing your JavaScript code to execute as soon as possible. This is the whole point behind using onDOMReady over Window onLoad.

nbga.js – A Non-blocking Integration

I think of Google Analytics as a log sink, something that just sits there in the background that allows me to tell it when it should track a page-view and stays out of my way otherwise. With this type of thinking, users of my website/webapp and my JavaScript shouldn’t be affected by or notice my analytics “log” running.

Update (2009-02-16):

I’ve updated this code to correctly accept a custom adapter to implement the object merge and get script functions. I’ve baked in adapter support for YUI 3, YUI 2, and jQuery; tested with YUI 3.0.0pr2, YUI 2.6.0, and jQuery 1.3.1. Also added a version number string to the file and versioned this one 1.0.

Re-gaining Control

Giving yourself more control over your Google Analytics integration is the key to solving issues that arise when adding it to your website/webapp. Creating a different general purpose Google Analytics integration with non-blocking of the DOM in-mind we regain control over when Google Analytics is loaded and executed.

General Usage

ga().config({ id:'UA-xxxxxxx-x' }).track();

There is two three functions being called here in a chain (but they do not have to be chained together):

The ga Function checks for the appropriate JavaScript library adapter: YUI 3, YUI 2, or jQuery. Optionally a custom adapter can be passed as an Object to the ga Function, implementing object merge and get script functions. Note: this function is only called once!

The config Function handles setup and loading of Google Analytics. This function takes an Object that requires an id property to be set to your Google Analytics Account ID. Optionally a sub Object, url can be specified to provided alternate URL(s) which to load Google Analytics from (i.e. locally hosted).

The track function will record a page-view in Google Analytics. A String can optionally be passed as the relative URL to track; this can be useful in tracking Ajax calls.

A different feature of this integration is that track can be called at anytime, even before config, and anytime after config which may be before Google Analytics has fully loaded and initialized. Requests to track page-views are queued if Google Analytics hasn’t been loaded or initialized at the time of the call to track. It is important to note that config must be called at some point to actually register page-views with Google Analytics.

YUI Usage

If you’re already using YUI in your website/webapp this is a simplified example of how you could integrate the script. I’ve created a working example to demonstrate nbga.js with YUI. To use with YUI the Yahoo Global Object and Get Utility are required to be loaded; using the yuiloader-dom-event.js roll-up file loads both of these modules and I recommend using it as your default starting point with YUI anyways.

<script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yuiloader-dom-event/yuiloader-dom-event.js"></script>
<script type="text/javascript" src="path/to/nbga-1.0-min.js"></script>
<script type="text/javascript">
	YAHOO.util.Event.onDOMReady(function(){
		// Your JS code...
	});
	ga().config({ id:'UA-xxxxxxx-x' }).track();
</script>

jQuery Usage

Even though I personally use YUI, jQuery is becoming the most popular JavaScript library so I made sure to build in a jQuery adapter into ga.js :-). I also created a working example of nbga.js with jQuery.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script type="text/javascript" src="path/to/nbga-1.0-min.js"></script>
<script type="text/javascript">
	$(document).ready(function(){
		// Your JS code...
	});
	ga().config({ id:'UA-xxxxxxx-x' }).track();
</script>

Features [Over Standard Integration]

  • Asynchronous loading of Google Analytics
  • onDOMReady and window onLoad happen sooner
  • Integrated YUI and jQuery adapters (built to work with these libraries)
  • Flexible adapter pattern (implement merge, and getScript functions)
  • Queuing of track requests
  • Chaining support
  • A 1.25kb 1.5kb (0.7kb gzip) addition over Standard Integration

Get The Code

If you liked this post you can suppot me with a Tip

5 Responses to “Non-Blocking Google Analytics Integration”


  • Thanks for this code. I would really like to use this in our site to track ajax calls. Just one question: can I assign the "ga().config({ id:'UA-xxxxxxx-x' });" part to a variable in the main template and then call "variable_name.track('ajax_url');" in other places without breaking queuing?

  • @Alex You're correct, that would be the intended usage. By assigning your var to the result of calling config you're insured that queuing will work as expected.

    Let me know if anything comes up during your integration.

  • Looks good, but it seems to only exposes the track functionality. We have a very integrated GA setup with ecommerce tracking and events which required method calls inaccessible through this script.

    Is there some way to expose the whole API but still queue the method calls until after GA.js has fully loaded?

  • @Andrew I could imagine implementing a generic method on my script which you’d pass a Google Analytics API method name and the arguments you’d want to pass to that method. This would require some re-work of the queue’s storage and emptying.

    I’ll look into implementing this next time I do a round of coding on this script. I’ll ping you if I come up with something that seems like it would be useful to you.

  • that sounds great, I look forward to it!

Comments are currently closed.

Additional comments powered by BackType