Adding additional site speed metrics to Google Analytics: measuring First Input Delay (FID)

By Martijn Scheijbeler Published March 20, 2019

Web Analytics is still one of my pet peeves, and while I don’t get to spend a ton of time on it anymore these days, I still enjoy digging through blog posts and coming up with new ideas on what to track and how it can help for (speed) optimization. While I was looking through a big travel site’s source code a couple of weeks ago trying to figure out what we could improve, I noticed a Google Analytics event that was being fired that was ‘new’ to me. It was used to sent information about ‘interaction delays’ as an event. After digging, I figured out what it was, and as I couldn’t find a ton of information about the topic itself in relation to Google Analytics I think it’s worth a blog post.

Disclaimer: There is not a lot of new original material in here, a lot of the information can be found in old updates on the Google Developers Web Updates section, and most credits go to Philip Walton. But I think it’s worth giving these topics some more attention and providing some additional solutions on how to integrate this with Google Analytics.

Site Speed Reports in Google Analytics

The site speed reports in Google Analytics have been proven to be useful for optimizing average load times and identifying how long it takes for a certain page to load (page loaded). You can use the data to figure out if your server is slow (Server Connection Time and Server Response Time) or to look at Domain Lookup Time to see how long it takes for a DNS lookup. But have you ever noticed yourself that for some sites it takes a tiny bit while the page is loading to actually start interacting with it while it’s being painted (the JS/CSS scripts) on your screen? Mostly on slow connections, like your phones mobile network, this can be obvious from time to time. That’s why the following metrics can come in handy as they will start measuring the time to the first paint and the first input delay that can happen.

Why is this metric not already part of the reports? Google Analytics can only start measuring the data whenever you’re loading the script. The speed data that it reports on is being gathered through the Speed API in your browser, but other data for a metric like this isn’t part of that. It’s also a fairly technical metric as you will realize after this. So for most basic users, it would cause a lot of confusion I’d imagine.

First Input Delay – FID

The important definitions:

  • FCP – First Content Paint: The time it takes (in milliseconds) for the first paint (pixels) on the screen.
  • TTI – Time to Interactive: The time it takes for the page to start loading and to be fully interactive.
  • FID – First Input Delay: The time between the first interaction (click, scroll, JS) of the user and the time it takes for user input to be acted upon by the browser.

This FCP metric is already part of the reports that you might have seen in Lighthouse. The obvious problem with that is, is that it’s just a one-off metric. It could be different for your users and you likely want to have a higher sample size to measure this.

Measuring First Input Delays (FID)

So let’s talk about how useful this is actually going to be for your site, starting with the implementation for Google Analytics and Google Tag Manager. The ChromeLabs team has done an amazing job providing a small ‘library’ for tracking the performance metrics via JavaScript. So these are the steps to follow for tracking this in Google Analytics (Gtag/Analytics.js) and GTM:

Measuring First Input Delays in Google Analytics

The script that you have just included provides a Listener that can be used to check when an event needs to be fired or just to save it to the DataLayer.

If you’re using analytics.js add this to your HEAD (under the minified script and after initializing GA):

perfMetrics.onFirstInputDelay(function(delay, evt) {
  ga('send', 'event', {
    eventCategory: 'SiteSpeed Metrics',
    eventAction: 'First Input Delay',
    eventLabel: evt.type,
    eventValue: Math.round(delay),
    nonInteraction: true
  });
});

If you’re using gtag.js (GAs latest version) add this to your HEAD (under the minified script and after GA has been initialized):

perfMetrics.onFirstInputDelay(function(delay, evt) {
  gtag('event', 'First Input Delay', {
    'event_category': 'SiteSpeed Metrics',
    'event_label': evt.type,
    'value': Math.round(delay),
    'non_interaction': true
  });
});

Measuring Input Paint Delays in Google Tag Manager

The integration for Google Tag Manager is obviously a little bit more complex as you need to add a new Trigger and Variable.

window.dataLayer = window.dataLayer || [];
perfMetrics.onFirstInputDelay(function(delay, evt) {
  dataLayer.push({
    'event': 'first_input_delay', // Not necessarily needed if this loads before GTM is initialized.
    'first_input_delay_value': Math.round(delay)
  });
});

Create the Value:

Add it to the Google Analytics configuration, so it will be sent along either your Events or your Pageviews (really decide on this for whatever works best in your use case). In this case, I’ve added it to a Custom Dimension on a page level, but you can also easily send this to a Custom Metric to calculate averages.

Custom Reporting on Speed Metrics

When you’re using a custom metric to report on FID you can easily create a metric on a page level to show to average first input delay for a page type or template. In this case, I created an example of a report that will show this only for new visitors (who likely haven’t loaded assets like JS/CSS/Images that are cached).

Adding other speed metrics

This is just the First Input Delay that you could be adding as a speed-related metric to GA. If you do some digging and are interested in this topic I would recommend going through the rest of the events here. That will give you enough information and a similar integration to measure First Paint (FP), Time to Interactive (TTI).

All the resources on this topic:

Like I said in the disclaimer, I mostly wanted to make it easier to implement but all the documentation around how to set this up and what it entails can be found on these resources.