ANALYTICS

How does the Universal Analytics snippet work


David Vallejo
Share
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-123123123', 'auto');
  ga('send', 'pageview');

The first thing that may attract your attention is the function parameters, they look like a real word. Let start talking about what an "isogram" is, according to the wikipedia:

An isogram (also known as a "nonpattern word") is a logological term for a word or phrase without a repeating letter.

i,s,o,g,r,a,m are the variables names being used in the Universal Analytics Tracking Code, and we don't want to pass a duplicate variable name to it. So actually this is just a pun from the Google guys since any other word with not repeated letters could have been used.

You may wondering what values are being passed to the function, and to know that we'll need to look to the bottom of the Universal Analytics Tracking Code:

(function(i,s,o,g,r,a,m){ ... }
)(window,document,'script','//www.google-analytics.com/analytics.js','ga');

This means "window" variable is being passed as the "i" parameter, "document" as the "s" parameter and so on.

At his point we could translate the Universal Analytics Tracking Code as:

      window['GoogleAnalyticsObject'] = 'ga';
      window['ga'] = window['ga'] || function() {
          (window['ga'].q = window['ga'].q || []).push(arguments)
      }, 
      window['ga'].l = 1 * new Date();
      a = document.createElement('script'),
      m = document.getElementsByTagName('script')[0];
      a.async = 1;
      a.src = '//www.google-analytics.com/analytics.js';
      m.parentNode.insertBefore(a, m)

Let's look to the code line by line to see what it does:

window['GoogleAnalyticsObject'] = 'ga';

It creates a new global variable named "GoogleAnalyticsObject" that holds the main Universal Analytics object name.

window['ga'] = window['ga'] || function() {
          (window['ga'].q = window['ga'].q || []).push(arguments)
}

Here the main ga object is created. If it is already defined then nothing happens, otherwise it will be declared as a function.
This function will create a temporary window['ga'].q array and then push all the arguments that we pass to the function to that temporary array ( ga('value',value'); ). It's done this way as it may  happen that the very first ga(); calls may come before UATC has been executed. It saves them in that array and after the code has been executed it will process them. From this point on, subsecuent calls will be directly processed.

window['ga'].l = 1 * new Date();

This sets a new object property with the current timestamp value. Yes, multipling a javaScript Date object by 1 returns the current Date variable timestamp value.

a = document.createElement('script')

A new a new script element is created and saved into a variable named 'a' . This is what what will be injected into the page's DOM, but not before some other things are set.

m = document.getElementsByTagName('script')[0]

Here the code looks for the first 'script' tag available on the DOM at the runtime, This will be used to attach the Universal Analytics tag before it.

a.async = 1

Sets the asynchronous attribute to our script tag, this will ensure the script will be run at the first opportunity after the script source is downloaded and before the window.load event without blocking the page parsing. Some browsers support the "defer" attribute which is the same as "async" but it will comply with the scripts order, again without blocking the page load.

a.src = '//www.google-analytics.com/analytics.js'

Now the src attribute is set for the script tag. This is from where the UATC is loaded. As you may have noticed the Schema is not specified, so it will be loaded from the current loading page schema, that is, if the page is loaded from https, the script will loaded from https://www.google-analytics.com and if the page is not under https, it will be loaded from http://www.google-analytics.com

m.parentNode.insertBefore(a, m)

Here is where the Universal Analytics Tracking Script is being injected into the page's DOM, The first 'script' found on the page is being passed, looking for its parentNode, and then injecting the Tracking Code right before it.

So this is basically how the UATC code works. I'm aware that my english on this post may not be the best, so any improvement over my explanations will be welcomed.

Note: Simo-san just adviced me about this post that talks exactly about the same topic: http://code.stephenmorley.org/javascript/understanding-the-google-analytics-tracking-code/ , so you may want to check it too :)

Thanks to Ranyere Rodrigues for helping me to improve the post with some english corrections :)