Skip to Main Content

How to Measure Page Load Time With Google Analytics

I’ve been playing around with Google Analytics’
Custom Variables feature and put together a neat integration that lets us measure the real performance of visitors to our website. It’s a little clumsy since Google Analytics wasn’t really meant to do this, but it’s good enough that many of you might find it useful.
Before we get started, here’s how it works:

  1. When a visitor lands on our landing page, we capture some timing information to measure the page load time.
  2. We’ll record that page load time in a Session scope Custom Variable.
  3. The page load time is reported to Google Analytics with the trackPageview call.
  4. The data is aggregated in Google Analytics and can be viewed in the Visitors > Custom Variables section.
  5. We need to export the data into excel to do anything useful with it because Google Analytics isn’t too good at dealing with numerical data in custom variables.

Now, here’s the step by step:

Step 1: Add some javascript to the header of your page

The first thing we need to do is make sure we can capture the page load time. I only did this on the landing page for our test website because what I cared about most was the performance of the first page a visitor sees when they come to the site. If you put this on every page on your site, it’s going to overwrite the pageload time value on each page they visit. This may lead to unexpected behavior since the times getting reported will be the performance of the _last_ page the user visits on your site. If you have multiple landing pages on your site, you can add this tag to each of them. I’m working on updates that allow you to track all of the pages on your site.

It’s important that you do this as the very first thing so you capture the timestamp as soon as possible. So the following code should be inserted in your head section as the very first element:

<script type="text/javascript">
var page_load_start = new Date();
var _gaq = _gaq || [];
window.onload = function() {
var page_load_end = new Date();
var load_time = page_load_end.getTime() - page_load_start.getTime();
load_time = parseInt( load_time / 100 )*100;
<!-- Here goes the rest of your head section --/>

There’s a couple things happening here so let’s walk through that code.

Capture the start time and initialize GA async tag

    var page_load_start = new Date();
var _gaq = _gaq || [];

The very first thing we do is capture a timestamp. This will get called in the browser as soon as it starts reading the head section. Now this isn’t a perfect way of measuring the start of page load time because at this point the browser has already downloaded the html and started reading it. I’m going to follow up on this post with a version of this code that uses the web timing api to get an even better measurement.

We are also using the Google Analytics async tag which we initialize here with the _gaq variable.

Set up an onload handler to capture stop time and compute page load time

   window.onload =  function() {
var page_load_end = new Date();
var load_time = page_load_end.getTime() - page_load_start.getTime();
load_time = parseInt( load_time / 100 )*100;

Next, we set up an event handler that will get called when the body of the page has loaded. Inside this handler we’re going to capture another timestamp to mark the end of page load. We can then compute the amount of time the browser spent between our timestamps to tell us actual page load time. We round off the load time to the nearest 100 milliseconds. This will help make our data set less sparse when we go to report on it.

Assign load time to a custom variable and report to Google Analytics


Now that we have a load time for the page, it’s time to get that data into Google Analytics. We use a custom variable to associate the load time with the visitors session. This means that GA will track this variable and associate it with all of the pageviews for this session. Make sure you replace UA-xxxxxxxx-y with your own account id.

If you’ve already got the trackPageview call on your page, you’re going to want to replace it with the code above. If you call trackPageview twice, you’ll double count the visitor, so make sure you are only calling it once per page.

Step 2: Add the Google Analytics async code to the footer of your page

If you’ve never used the async tag for Google Analytics, now’s the time to start. Basically, this decouples Google Analytics from your page load process. Here’s Googles
introduction to the async tag.


<!-- Your web page goes in here --/>

<script type="text/javascript">
(function() {
var ga = document.createElement('script');
ga.type = "text/javascript"; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'https://www') + '';
var s = document.getElementsByTagName('script')[0];

This code is copied right out of the google analytics documentation.

Step 3: Deploy and wait for data

Now that we’ve got the code installed on our landing page, we can deploy to our production site. It will take a while before we see any data. We need to wait for actual visitors to come to our site and give Google enough time to process the data. This may take as little as a couple hours, but I waited a day before coming back to it. Now’s our chance to go use the little hackers room and catch up on our yslow optimizations. Better yet, why not go and learn more about
web performance optimization at Yottaa!

Step 4: Analyze your web performance data

OK so we deployed the code, waited a while for the data to collect. Now it’s time to dig into the data to see what’s happening on our site.

To get to your data, log into your Google Analytics account and go to the Visitors > Custom Variables section by navigating through the left hand menu. You should see something like this:

You’ll see our custom variable: landingPageTime and some summary statistics about it. If you don’t see this and it’s been 24 hours, you may have a problem with your tag (or you may have no visitors to your website). Go back to step 1 and make sure you installed the tag correctly.

If you click on landingPageTime, you’ll see the detailed report for the variable. It should look something like this:

Now this data might look a little confusing at first. Here’s how to read some of the more important columns:

    • Custom Variable: This column contains the actual page load time reported by the tag. So if it says “900”, that means 900 milliseconds. The rest of the row shows you statistics for all sessions where the landingPageTime was 900ms.

    • Visits: This tells you how many visits to your site had that landing page time. So if it says “100”, that means 100 people came to your site and experienced a page load time of 900ms.

    • Pages / Visit: This tells you how how many pages were viewed by users who experienced this row’s load time. To be honest, this data looks a little wonky on my own test site and I’m wondering if there’s something going wrong on the data collection. But theoretically, this should let you see if a faster loading time leads people to visit more pages.

    • Bounce Rate: This tells you the bounce rate for sessions that experienced this load time. I find this to be the most interesting column because it shows you if bounce rate changes when the load time changes.

Now the big problem I have here is that Google Analytics just isn’t designed to report intelligently on this kind of data. It treats our load time variable as a string, so the table does not sort properly. Also, the graph at the top of the page is pretty meaningless.

So what I do here is export the data to excel and finish my analysis there.

Results for My Testing Site

We’ve been running this tag on our testing site for the past month or so. Here’s some of the interesting charts that I created in excel.

Distribution of page load time

Distribution of page load times

Here we can see the distribution of page load times for our visitors. We can see that the majority of our landing page views happen in less than about 4 seconds with some stragglers going out to about 10 seconds. What you hope to see here is that all of our visitors are on the left hand side of this graph.

What’s great about this chart is that we’re looking not just at an average page load time, but real measurements from every single visitor to our site. We can see exactly how many visits were out in the upper percentiles of performance and how big a problem those visits really are and whether or not we should be investing time in fixing it.

In general, when working on performance, we want to be looking at percentiles rather than absolutes. Asking for 100% of pageviews to happen within some time is practically impossible. A much more reasonable goal is to say that 95% of all visitors should experience a load time of less than Xms. This is achievable.

Bounce rate by page load time

Bounce rate by page load time

This chart shows how page load time impacts bounce rate. We can see what the bounce rate was for each page load time that was experienced at our site. I added a linear trend line to the data so you can see the trend. You can see pretty clearly that bounce rate on the left hand side (fast page load time) of the chart is much better and less erratic than the right hand side. We see that after about 5 seconds, our bounce rate jumps significantly.

This chart helps us understand how tolerant our users are of performance degradation. Based on this chart, I would say that our 95% goal for performance is about 5 seconds since under that rate we maintain a pretty consistent bounce rate.

Thoughts and next steps

I’m pretty psyched about this data. This was all put together with a couple lines of JavaScript, a free google analytics account, and some basic excel charting. It suffers from some problems though:

    • The way we measure page load time is not great. It works in all browsers, but it ignores the time the browser spends fetching the initial page (since that happens before we hit our tag in the head) and it ignores stuff that happens after the onload event. I’m going to update this code to use the web timing API so we have better measurements.

    • Google analytics is not very good at visualizing this data. It was obviously designed with some different use cases in mind. Right now, exporting the data to excel works okay, but I would really like some automation. We’re working on some cool features to automate this at yottaa and you should check back as we put some of this stuff online.

    • We’re only measuring landing page performance. My next step is to expand the javascript tag so we can capture more data about performance of all pages on the site.

[UPDATE: Here is an updated gist (HTML and JavaScript code fragment) for this feature, leveraging the W3C Nav Timing API for browsers that support it.]

(The original gist with the code documented in this feature is here.)

That’s all for now. Try it out yourself and let me know how it goes!


10 User Engagement Metrics Everyone Can Use


Don’t let slow site performance cost you conversions.Let's Talk