Single page apps are always a battle for a robust Google Analytics implementation. From correct page titles, rogue referral problems, to when to fire page views, nothing is inherently simple. To add onto the list of complications with single page apps is the fact that Google Analytics will not provide page timings (once loaded between internal pages) for SPA’s. This includes if you increase the site speed sample rate to 100. This is because Google Analytics calculates the page timings using the Navigation Timing API.

For example, DOM loaded would be:

$(document).ready(console.log(( - 

To over come this problem, you will need to use custom metrics. The solution has three steps.

1) Set up a custom metric in GA.

Go to Admin > Property > Custom Definitions > Custom Metric.

Create a new Custom Metric, with the scope of Hit and the formatting type of time. Note: Specify time in seconds, but it appears as hh:mm:ss in your reports.

2) Set up a timer.

You will need to capture the time when you want to start the measurement of page load time.

An example solution to this might be by decorating all of your internal links. For example in Google Tag Manager we could set up a Custom HTML tag:

  time1 =

3) Send the time eclipsed (in sec) to Google Analytics on the virtual pageview event.

When the virtual pageview event occurs (which triggers your virtual pageviews), retrieve the difference between the current time ( and the time which the timer was started (time1).

Using Google Tag Manager, a Custom JavaScript variable (e.g. SPA load time) can be created as below:

  return ( - time1)/1000

This value then needs to be sent with the pageview, against the custom metric index set up in step1.

SPA pageview example

Using the custom metric along with calculated metrics (e.g. {{virtualPageTimings}}/{{pageViews}}, you will be able to calculate your average virtual page timings.


To make the measurement more accurate, set up a secondary custom metric to count the number of virtual pageviews. This will make sure that landing pageviews are not taken into consideration.

To do this, create a custom metric with the scope hit and the formatting integer.

Then with every virtual pageview, send the value 1 against the custom metric index. E.g:

SPA page load speed 2

This allows for the calculated metric:



Using this calculated metric will then give you a good idea of how long a SPA page took to load, from the time which a user clicked on a link through to that page.

This is just one aspect of what is needed to be taken into consideration when working with single page apps. Feel free to reach out if you require any assistance tracking your SPA.