Faster, Better, Stronger. The GA Async Tracking Code

Notice: Undefined variable: attachments in /home/justincu/public_html/blog/wp-content/plugins/sociable/includes/sociable_output.php on line 139

You may have heard that Google will begin to use site speed when calculating web rankings. This generated a lot of buzz, but according to Matt Cutts,

fewer than 1% of search queries are affected by the site speed signal in our implementation and the signal for site speed only applies for visitors searching in English on at this point.”

This may be the beginning of Google’s use of site speed. It’s probably a good idea to think about speed when designing your site.

How GA can Slow Your Site

One thing that can potentially slow your site down is the Google Analytics tracking code. Specifically, the ga.js library and how the browser loads the file.

When a browser renders a page it literally starts starts to display the HTML from the top of the page and moves to the botton. When it hits a JavaScript file, like ga.js, it requests the file from the remote server.

Then it waits.

And waits.

And waits.

Once the file has been pulled into the browser it continues to process the HTML.

You can see the issue here, the browser could wait a long time for the JavaScript file depending on the visitors proximity to the server, the visitor’s bandwidth, and a bunch of other factors most of which you can’t control. Waiting for a page to render is a bad user experience. I know I don’t like to wait!

There’s a great example of how a remote file can make the browser slow down on the High Performance website blog.

Google tries to mitigate load-time issues by geo-loadbalancing ga.js, so the visitor’s browser will automatically contact the closest data center to load the ga.js faster.

It’s also best to place the ga.js at the bottom of your pages just in case there is an issue with the communication between the data center and the visitor’s browser. By placing the ga.js at the bottom of the page all of the content has already rendered, so the visitor won’t experience a blank or partially loaded pags.

While placing the GATC at the bottom of the page can mitigate some issues it can cause others.

First, it is possible for visitors to navigate away from the site before data is sent to Google Analytics. This leads to missing data.

Second, if you need to do any advanced tracking, like ecommerce or events, you may need to move the ga.js to the top of the page thus negating the benefit from putting it at the bottom of the page. This can also complicate your implementaiton because some pages may have the code at the top of the page and some might have the code at the bottom of the page which is a maintenance nightmare.

Using the new async code can help mitigate both of these problems.

How the Async Code Helps

First, The asyncronous version of the tracking code utilizes HTML 5 and the modern browser’s ability to load files asyncronously. This means that the browser can load files like ga.js while it continues to render the page for the visitor.

Second, the async code let’s us send data to Google Analytics before the ga.js has loaded in the browser. Technically we’re not sending the data to Google, but we are executing the commands that generate the data. The broser just holds the commands until the ga.js has completely loaded. Then the commands are executed (in the order in which they were added) and the data is sent to Google.

In the old days (like last year) we had to wait for ga.js to load before we could call any GA code. Not any more.

So the Async code is a good thing.

The big question is, should you use the async tracking code?

Well, if you’re concerned that Google Analytics is slowing down your site, and that it may be impacting your search rankings, then yes, use the async code. There are a number of free tools that you can use to test how long it takes ga.js to load on your site. (YSlow, Page Speed, etc.) Use them to determine if GA is slowing down your site.

If you decide to use the async version of the code there are a few things you should know.

Using the async code is slightly different than using the standard tracking code. Let’s look:

< script>
// This section creates the queue
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);

// This section calls the ga.js
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);

The async code can appear anywhere in a page. But it’s best to place it at the immediately after the opening BODY tag. This let’s you add commands to the queue as soon as the page starts to render.

Some of the GA documentaion states that you can place the code in the HEAD tag. But this can cause some JavaScript issues with IE6. If you have a lot of visitors that use IE6 don’t put the code in the HEAD tag.

If you’re still leary about putting the code at the top of the page you can split the tracking code into two sections. You can place the first part of the code at the top of the page and the second part, the calls the ga.js, at the bottom of the page.

While this let’s you add commands to the queue immediately it is still possible to miss some GA data becayse the ga.js will be the last thing the browser requests. But the choice is up to you.

How the Code Works

Digging into the code a bit more, the first thing you’ll notice is the call for the ga.js is the second part of the code. This is the opposite of the standard tracking code. The async tracking code begins by creating the queue to store commands. Then the tracking code calls Google’s servers for the ga.js file.

The great thing about the queue of commands is you can add things to the queue whenever you want, even if the ga.js has not finished loading. This is what makes it possible to add GA commands at the top of a page.

The second section of code is the request to Google’s servers for the ga.js. It’s the exact same ga.js that’s used in the standard tracking code, it’s just pulled into the browser in a different way. Notice the ga.async=true part of the code? That’s the part that tells the browser it should load the code asyncronously. The browser not execute any commands in the queue until after the ga.js has loaded.

If you’ve got a basic site then all you need to do is add the async code to your pages and you’re good to go. You don’t need to worry about adding items to the que, etc.

But if you’re doing any advanced tracking, like virtual pageviews, events or ecommerce you need to know how to add items to the queue.

How to Add Items to the Queue

Adding items to the queue can be done a number of different ways. The easiest way is to “push” things onto the queue. This is done with the push command, as shown below.

_gaq.push(['_setAccount', 'UA-XXXXX-X']);

If you wanted to add an event to the click of a link you would push the command on to the queue like this:

< a href="onClick='_gaq.push(['cat','act','label']);'">go red sox< /a>

Or, to create a virtual pageview you could push the command onto the queue like this:

< a href="onClick='_gaq.push(['_trackPageview','/virtual/go-red-sox']);'">go red sox< /a>

You can also add mulitple commands to the queue at a time. But this is where things start to get technical, and I’m not going to go there :)

How you implement the code depends on your site, the commands you want to add and how much JS you know. To learn more about how to add commands check out the GA Code site.

Switching to the Async Code

The complexity of migrating to the async tracking code depends on your site. If you’re not using any of the advanced GA features then migration can be as simple as swapping the tags.

But, if you are using advanced features, you’ll need to update all of the GA code on your site. Remeber, all the standard Google Analytics functionality in the ga.js exists in the async code. You just need to replicate your existing code in the async format. You can find an overview of the async code (written in nerd) as well as code examples, on the Google Code site.

Obviously the migration effort depends on the complexity of your implementation. But if you take your time and document your existing GA code and test your implementaiton thoroughly everything should go smoothly.

Have you tried the new async code? Got an experience you want to share? Leave a comment!

Be Sociable, Share!

    Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; MCAPI has a deprecated constructor in /home/justincu/public_html/blog/wp-content/plugins/mailchimp-widget/lib/mcapi.class.php on line 3

    Like this post? Sign up to get posts delivered to your inbox.


    1. says

      Great article! One of the best I’ve seen on the subject.

      One thing though…the async snippet _is_ safe to put in the HEAD of your page, even in IE6. The previous version of the snippet, which used appendChild instead of insertBefore _did_ have a problem with some pages in IE 6 and 7. That has been fixed. The current snippet is safe to put anywhere inside the HEAD or BODY on any page.

    2. says

      I have an experience I like to share: if you start using the Async tracking code you could get some changes in for example your visit-count and bouncerate. People that clicked away very quick where not tracked before. Those are more likely to be tracked with the new code, but because they click away they will be counted as bounces.

      • Justin Cutroni says

        @Julien: HA! So true, can definitely be considered be virtual right now.

        @Andre: Great point! Your data could absolutely change when you implement the async code. It could get a lot better!

        @Brian: Thanks Brian, I appreciate it. I didn’t feel like there was a good overview of the code out there, something everyone could understand. And thanks for correcting my IE6 reference. I’ll update the post.

    3. says

      I’ve tried it, and quickly abandoned it. It was simply too complicated to get e-commerce tracking up and running.

      Although the reason for this is prolly not the code’s fault, but rather my lack of coding skills :-P

      Async tracking is a very good idea. But I’m holding off on implementing it until more people have tested it and blogged about it.

    4. says


      I’m trying to convert some code for a netsuite e-commerce site. I would like for it to track both google checkout and netsuite checkout. The challenge here is that the domain changes when visitor goes to shopping Cart. Anyway you can point me in the right direction?

      —-Old Code from Netsuite—-

      var gaJsHost = ((“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”);
      document.write(unescape(“%3Cscript src='” + gaJsHost + “’ type=’text/javascript’%3E%3Cscript%3E”));

      var pageTracker = _gat._getTracker(“UA-XXXXX-X”);

      onsubmit=”setUrchinInputCode(pageTracker);return true;”

      —–My Best Guess————

      var _gaq = _gaq || [];
      _gaq.push([‘_setAccount’, ‘UA-10828726-1′]);
      _gaq.push([‘_setDomainName’, ‘none’]);
      _gaq.push([‘_setAllowLinker’, true]);
      _gaq.push([‘_setAllowHash’, false]);

      (function() {
      var ga = document.createElement(‘script’); ga.type = ‘text/javascript'; ga.async = true;
      ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’) + ‘';
      (document.getElementsByTagName(‘head’)[0] || document.getElementsByTagName(‘body’)[0]).appendChild(ga);

    5. says

      Sorry…Code did not display

      ——async version—–

      onsubmit=”_gaq.push(function() {var pageTracker = _gaq._getAsyncTracker();setUrchinInputCode(pageTracker);});”

    6. Matt Clark says

      I’ve just being weighing up whether we should migrate our enterprise clients here at Summit the new tacking code, and once again you have summarised all the key consideration points clearly and concisely in one post.

      Thank you!

      PS: All the best with your new position, are you still going to be conducting seminars in the UK?


      • says

        @Taylor: If I remember correctly, and it’s been a while, but when you’re using Google Checkout the setUrchinInputCode(pageTracker) command sets some hidden fields. And that command is part of a completely different JS include. You should be OK to keep using that code. As for the cross domain, here’s how you would set that up when using async: Let me know if it works!

        @Matt: Thanks so much, IO really appreciate the well wishes. A few UK companies are going to start doing more of the UK seminars. But I’ll be over there for a few events this year.

    7. says

      @Justin great to see you are back with some blog posts and thanks for an update how to track with the new code!

      I tried it last month, but the modules didn’t seem to work well with it, and the fact that i have to change a clients tracking, might leave it for a bit longer.

    8. Seth says

      1. Your example for a virtual page (used in setting goals) does not use brackets:

      You say: Or, to create a virtual pageview you could push the command onto the queue like this:

      go red sox

      But all of the examples I see for gaq.push have both a parenthesis and a bracket and would seem to require the code to be:

      go red sox

    9. says

      Yeah, one more great post, Justin!
      By the way, have you ever tried to use multiple asynchronous trackers on the same page, for roll up account reports?

      Maybe this thread would be a great post for the community, huh?
      I’ve seen so many posts on this thread with unclear answers.
      I’ll send you a problem i’m facing and maybe it gonna be a nice suggestion on a new post to Analytics Talk.

      Thanks and keep posting!

    10. Leo says

      I’m guessing that the CRM integration code will need to be tweaked so that execution occurs after ga.js has created the cookie. Anybody know how best to do this?

    11. Ana says

      Thanks Justin for another great post!

      Migration to asyncronus code worked fine for me (so far), but still I’m thinking about how to handle a tracking of new visitors with custom variables in asyncronus code.

      To identify a first visit I first check if there is any __utma. If not (new visitor) I read the referrer (medium, source, keyword) out of __utmz and write it into a custom variable. So far, so good, but how can this be done with asyncronus code? Any idea?



    Leave a Reply

    Your email address will not be published. Required fields are marked *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

    Notice: Undefined variable: update in /home/justincu/public_html/blog/wp-content/plugins/subscribe-to-comments.php on line 730

    Notice: get_settings is deprecated since version 2.1! Use get_option() instead. in /home/justincu/public_html/blog/wp-includes/functions.php on line 3507

    Notice: Undefined index: default_subscribed in /home/justincu/public_html/blog/wp-content/plugins/subscribe-to-comments.php on line 266