VKI Studios is now Cardinal Path! www.CardinalPath.com
Learn more about Cardinal Path

Slow web page loading times? Track them with GA: Google Analytics Power User 12


Your users don't want to wait

Did you know that Google Analytics can track how long it takes your web pages to load?

Slow loading web pages frustrate users and provide a poor user experience. There are a bunch of different tools to help you measure the size of your web pages in kb but what you really want to know is on average how long it takes you user to load each of your pages (measured in milliseconds). Beyond that you want to know how the visitor's connection speed is influencing page load times.

To get Google Analytics to track page load times you will need to set up 'Event Tracking'. Currently, to enable this feature you need to submit a request to Google from the event tracking documentation page.


Update: We've included the newest scripts here:
timeTracker.js

pageLoadTracker.js

The following code is based on the TimeTracker object written by Google. The original source code can be found here. We've updated the original source code to use the most current API calls (the original uses deprecated functions).

There are two objects used: TimeTracker which is the generic time tracking class (it can be used to time anything) and is also responsible for sending out the event tracking request to Google; and PageLoadTracker which is a wrapper for the TimeTracker class, and is specifically used to track page load times.

There are two snippets of code that need to be added to the page. The initialization code which should go as close to the opening tag as possible, and the window load event listener code which should go as close to the closing tag as possible.

Initialization Code

<head> <script type="text/javascript"> var startTime = (new Date()).getTime(); </script> <script src="/external/js/timeTracker.js" type="text/javascript" language="javascript" charset="utf-8"></script> <script src="/external/js/pageLoadTracker.js" type="text/javascript" language="javascript" charset="utf-8"></script> <script type="text/javascript"> var pageLoadTracker = new PageLoadTracker('pageTracker', 'index.cfm', startTime); </script> ... </head>

The PageLoadTracker constructor takes one required argument, and two optional arguments.

The first argument is the variable name of the Google Analytics page tracker object.

The second argument is the name of the index page. If you pass in 'index.html' as the second argument, visiting 'www.example.com' and 'www.example.com/index.html' will both show up as 'index.html' in the GA reports. This also works for subdirectories. So visiting 'www.example.com/dir/' and 'www.example.com/dir/index.html' will both show up as '/dir/index.html' in the GA reports.

The third argument is used to specify a start time. Without the third argument, timing is started when the PageLoadTracker object is created. If you want to track the load time including the time required to load the TimeTracker and PageLoadTracker Javascript files as well, you need to record the timestamp before including the scripts, and pass that timestamp in as the third argument to the constructor.

Event Listener Code

<body> ... <script type="text/javascript"> addListener(window, 'load', function () {pageLoadTracker.track();}); </script> </body> </html>

This code adds an event listener that fires after the page and external files (images, javascript, css, etc) have been downloaded and displayed by the browser. Once the event is fired, the pageLoadTracker sends the event tracking request to the Google servers.

CAUTION! Because you are using events in this way you will corrupt your bounce rate metric. Because the TimeTracker event is being fired on every page Google Analytics thinks that the user has taken an action on every page and therefore hasn't bounced (you will still have some people bouncing as they actually are real bounces who bounced prior to the entire page loading, but this number will likely be much smaller than your actual bounce rate). The way around this is to populate 2 separate Google Analytics accounts by double page tagging. This way you will have one account in which the TimeTracking event is fired and one in which the time tracking event isn't. The account that is collecting the TimeTracking information will not have an accurate bounce rate while the other account will maintain an accurate bounce rate metric.

Another consideration when setting up the TimeTracking is how you will breakdown or categorize the different time intervals. In most cases we feel that the following millisecond break down is appropriate:

0-999
1000-1499
1500-1999
2000-2499
2500-2999
3000-3499
3500-3999
4000-4499
4500-4999
5000-5499
5500-5999
6000-6499
6500-6999
7000-7499
7500-7999
8000-8999
9000-9999
10,000-14999
15000-19999
20000+

Something else you will likely want to do is create a few advanced segments based on visitor connection speed (cable, DSL, T1, Dialup, ISDN, Unknown). I usually create one segment titled broadband and include Cable, DSL, T1 and a second which is Dialup and a third which is ISDN. By creating these advanced segments you will be better able to understand if slow loading times are as a result of the visitors connection speed, or if they are a result of heavy pages, server issues…



Edit: As requested in the comments here is the page load time tracking within the Event Tracking reporting:

click for full size


Anyhow, if you find this useful, sphinn it:

or hit up one of the other sharing options in our "share this" bar below.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
I worked with a client recently that was monitoring page load time using Event Tracking and had also set up several segments using custom filters and profiles based on URL.

We found that we couldn't filter out the visits being generated by Event Tracking. So, each of the profiles (segments) showed a similar number of visits when we knew they should have vastly different numbers.

So, just a case in point that using Event Tracking may affect your reporting if you're segmenting visits into separate profiles based on URL.
# Posted By JH | 5/24/09 5:42 PM
Great post. One thing that is often overlooked is load times for users. Glad that there is a way to track this.
# Posted By Stefanie Hartman | 5/25/09 5:39 AM
Hey can you please post a screen shot of page load time tracking through Event Tracking reporting interface.

Thanks,
BJ
# Posted By Bhagawat | 6/8/09 11:20 PM
Did you still keep the Analytics code as being the very last thing in the page (before </body>)?

How were you setting up to track 2 Analytics accounts at once?

I tried setting up the 2 accounts as follows:

var firstTracker = _gat._getTracker("UA-xxxxxxx-1");
      firstTracker._initData();
      firstTracker._trackPageview();
      var secondTracker = _gat._getTracker("UA-xxxxxxx-1");
      secondTracker._setDomainName("none");
      secondTracker._setAllowLinker(true);
      secondTracker._initData();
      secondTracker._trackPageview();

Which gave a JS error "_gat is not defined". I repaired the error using the method suggested in the comments on the post below:
http://vpxcc.wordpress.com/2008/06/06/howto-solve-...

if (typeof(_gat) == 'object') {
// Analytics code here
}

..but then nothing is tracked?
# Posted By Chris Ward | 8/11/09 12:56 AM
@JH - Hostname filters will now work with event tracking and event tracking can also be used in Advanced Segments now. This should help resolve the issues you were seeing.

@Chris Ward - Don't forget you still need the link to the GA.JS code above what you posted in your comment. If _gat is not defined, it indicates to me that you haven't included the script to link to GA.JS


<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol)
? "https://ssl."; : "http://www.";);
document.write("\<script src='" + gaJsHost
+ "google-analytics.com/ga.js' type='text/javascript'>\<\/script>" );
</script>
# Posted By Dave Eckman | 8/13/09 9:31 AM
@Chris Ward - The other thing you will want to ensure is that you are inserting the page load tracking into a totally separate web property ID. In the code you submitted, your example ID's are both UA-xxxxxx-1
# Posted By Dave Eckman | 8/13/09 9:35 AM
Nice, but you are not measuring the complete page load time.
Since you initialize the timer with a Javascript in the head section on the same page, you miss out on the first part of time it takes for the page load in the browser, which includes DNS lookups, loading the HTML, loading the timeTracker.js, executing the timeTracker.js, etc.

What I really want to know is: how long does it take from the click on the link in the page before until the current page has loaded completely?
So what I need to do is initialize the tracking by adding an event handler to the links in the page before and storing a timestamp on click and then calculating a diff on the following page.
I have done a standalone example of this using javascript and cookies:
http://www.hoc.net/~mike/source/page_load_rtt/

Now it would be nice to see it integrated into google analytics - any volunteers? ;-)
# Posted By Dofa | 11/5/09 3:03 AM
Google Analytics is very nice in that it provides a data warehouse for storing tons of information. Using GA's TimeTracker is a great idea. A problem with your code recommendations is in attempting to measure page load time, you're actually making the page load more slowly. GA has come out with a new async snippet ( http://code.google.com/apis/analytics/docs/trackin... ). It turns out, you can load timeTracker.js asynchronously, too. Another recommendation is wrt the time intervals (what GA calls "Histogram Buckets"). My guess is, if you ever change these buckets, all the previous data remains unchanged. Therefore, it's important to start with buckets that you believe will never change. I'd recommend doing a histogram every 100 ms. My final wish is that there was a better way to slice and dice the data. The GA pages, for example, sort alphabetically, so 200 comes after 1500. Numerical sorting would be better. It'd be awesome if someone posted a way to export the data from GA and chart it better. Or maybe a bookmarklet or browser add-on.
# Posted By Steve Souders | 4/29/10 9:00 AM
Hi Steve,

Some good points. Thanks for the feedback.

The javascript method is not perfect, but it's all relative with analytics and it definitely helps us identify slow loading pages. There are more complex implementations where you could actually use some server-side code to get more accurate load times that track from the time the request was received to the time the page was loaded.

Planning is definitely important when creating the histogram and when you're under 1 second, you may want to break it down even further, though a lot of the time, we're not trying to get that detailed with this method, we'd use some
server-side coding or other methods that are more accurate.

Unfortunately we haven't got around to updating our site to the async code or doing an updated post, but you could definitely use that.

In regards to exporting and slicing the data, you can export the data from the event tracking reports into a variety of formats by clicking the Export button at the top of those reports. OR, you could use the data export API built into GA ( http://code.google.com/apis/analytics/docs/gdata/g... ) to get even more flexibility with the data.
# Posted By Dave Eckman | 4/29/10 10:36 AM
Why not tracking page load times with a custom variable instead? According to http://analytics.blogspot.com/2009/01/using-setvar... it doesn't have the side effect of bounce rate that events do
# Posted By Harry Fuecks | 6/24/10 3:22 PM
Hi Harry,

That's a good question. This article was written before the new custom variables were released.

You could probably use a page-level custom variable with the name set to the time bucket, and the value set to the name of the page. But you may come across a couple issues doing it this way:
* average page load times must be calculated by hand
* you use 1 CV slot for the tracking which might better be served for tracking other things

If you use this method, let us know how it works for you.
# Posted By Dave Eckman | 6/24/10 4:52 PM
You're right, nice touch down on this article, thanks. In this new age of Web 2.0 simple things like backlinks or indexed pages have become trickier than before, just because of the many factors that the spiders have to consider. I used to check my domain seo values via http://ministatus.com , but it'll be just as good if one is doing it manually.
# Posted By dsf mini status | 7/6/10 11:19 AM
.