Blog Post

How Fast Is Your Web App? How to Test Page Transition Performance

Published
September 26, 2022
#
 mins read
By 

in this blog post

A complaint I sometimes hear about web performance metrics is that they focus too much on initial page load, unfairly skewering web apps that are actually fast but in different ways than traditional websites. The reasoning goes that many web applications are intentionally built more like native apps than like websites, prioritizing efficiency during lengthy browsing sessions after the web app is already open rather than optimizing for a first visit.

While I would argue that site delivery optimizations should not need to conflict with post-load optimizations (...and wonder if users carry their low performance expectations of native app startup time over to the web anyway), it is true that these represent different moments in user experience and need to be measured differently. Also, there are too-few resources on testing perceived performance of navigation after initial pageload. Let's fix that.

In this post, I'll demonstrate how to test a website's post-load navigation speed in WebPageTest. This process is something you can use on any kind of website, but may be particularly handy for testing single-page web apps that tend to handle page navigations on the client-side.

Testing Navigation Performance

To demonstrate, I needed a good web app example that typically involves a page change or two after initially opening it. Spotify's web player seemed like a good example, as a common flow for me in that particular app is to open its homepage and click on an album before beginning to play some music. I'll use open.spotify.com for this post, which is the homepage of their web player.

Enter a starting page URL

Like any test in WebPageTest, I'll start by going to the Start Test page and entering the URL I want WebPageTest to open:

webpagetest's homepage screenshot with the url in the field

Open Advanced Configuration

Next I'll want to open the Advanced Configuration settings as we'll be using a feature in there.

screenshot of the advanced tab

Script an Interaction

In the advanced section, I kept the test settings as the default (desktop, fast connection speed) and jumped to a specific section: the Script tab. The Script tab lets you instruct WebPageTest to do all sorts of things like setting cookies and headers, interacting with page elements, and much more. You can think of the Script tab as WebPageTest's command line, and the docs are here.

In this case, I'll want to tell WebPageTest to open my URL and then click a link in that page to navigate to another one. As a quick example, the following commands would do that:

navigate %URL%
execAndWait document.querySelector('.your-selector-here').click()

The first line says to navigate to a variable called %URL%, which is one of a few environmental variables WebPageTest offers that refers to the URL you typed into the initial form field in the test. That'll make WebPageTest load spotify's start page.

The second execAndWait command says to execute some JavaScript on that page and keep recording until the scripting finishes executing. In this example, I've used a JavaScript that finds the first HTML element with a class of "your-selector-here" and clicks it.

In Spotify's page, I'll need a real selector for the link I want WebPageTest to click, so I used my browser's devtools inspector to look at their source code and find a selector that makes sense to click. The grid items shown here contain links that sit inside a div with an attribute of data-testid="grid-container":

screenshot of spotifys page with a web inspector panel finding the right element in the DOM

This selector should work fine to use as a parent selector for the element I want to click:

navigate %URL%
execAndWait	document.querySelector('[data-testid="grid-container"] a').click();

That script will cause WebPageTest to click the first link that happens to be in that grid when I run the test.

Lastly, I want to instruct WebPageTest to only record during the second navigation and not the first. Then I can capture timing that is specific to just that transition. I can do this using the logData command. logData 0 tells WebPageTest to stop listening while I run a command or two. logData 1 tells it to start recording again.

I'll use logData to isolate my recording to the second step here:

screenshot of the script tab with the script text below entered in the field

In text, here's that script in full:

logData 0
navigate %URL%
logData 1
execAndWait document.querySelector('[data-testid="grid-container"] a').click();

That's it! To run the test, just hit that Start Test button!

Viewing the Test Results

When WebPageTest finishes, it'll show a result like this:

screenshot of a webpagetest result page

And as you can see in the filmstrip below, WebPageTest has captured the session between the homepage and the playlist page it navigated to.

filmstrip showing a first frame of the homepage and a bunch of loading frames before the eventual second page

So there we go, these results show that Spotify took 1.9 seconds to complete a navigation from one previously-loaded page to another.

As for the reported metrics however, it's important to note that some are more relevant than others.

Many metrics come from the browser instead of WebPageTest itself, and those metrics are recorded from the start page, making them unhelpful in this type of test. For example, Core Web Vitals metrics are not relevant in this kind of test because they are measured by Chrome rather than by WebPageTest, and Chrome doesn't stop recording with logData commands like our own metrics do. Other metrics fall into this group as well, such as first contentful paint.

In addition to the filmstrip visual, the metrics you may find most helpful in this comparison are:

  • Time to First Byte
  • Start Render
  • Total Time
  • Total Bytes
  • Total Requests

Enjoy!

We've barely scratched the surface here with scripted tests, but hopefully this will give you a starting point for measuring those navigations after page load. From here, you might try combining logData with more complex scripts exported from the new WebPageTest Chrome Recorder Extension.

And since you're here, maybe check out this post about measuring and improving those web apps' initial loading speed as well! Cheers.

A complaint I sometimes hear about web performance metrics is that they focus too much on initial page load, unfairly skewering web apps that are actually fast but in different ways than traditional websites. The reasoning goes that many web applications are intentionally built more like native apps than like websites, prioritizing efficiency during lengthy browsing sessions after the web app is already open rather than optimizing for a first visit.

While I would argue that site delivery optimizations should not need to conflict with post-load optimizations (...and wonder if users carry their low performance expectations of native app startup time over to the web anyway), it is true that these represent different moments in user experience and need to be measured differently. Also, there are too-few resources on testing perceived performance of navigation after initial pageload. Let's fix that.

In this post, I'll demonstrate how to test a website's post-load navigation speed in WebPageTest. This process is something you can use on any kind of website, but may be particularly handy for testing single-page web apps that tend to handle page navigations on the client-side.

Testing Navigation Performance

To demonstrate, I needed a good web app example that typically involves a page change or two after initially opening it. Spotify's web player seemed like a good example, as a common flow for me in that particular app is to open its homepage and click on an album before beginning to play some music. I'll use open.spotify.com for this post, which is the homepage of their web player.

Enter a starting page URL

Like any test in WebPageTest, I'll start by going to the Start Test page and entering the URL I want WebPageTest to open:

webpagetest's homepage screenshot with the url in the field

Open Advanced Configuration

Next I'll want to open the Advanced Configuration settings as we'll be using a feature in there.

screenshot of the advanced tab

Script an Interaction

In the advanced section, I kept the test settings as the default (desktop, fast connection speed) and jumped to a specific section: the Script tab. The Script tab lets you instruct WebPageTest to do all sorts of things like setting cookies and headers, interacting with page elements, and much more. You can think of the Script tab as WebPageTest's command line, and the docs are here.

In this case, I'll want to tell WebPageTest to open my URL and then click a link in that page to navigate to another one. As a quick example, the following commands would do that:

navigate %URL%
execAndWait document.querySelector('.your-selector-here').click()

The first line says to navigate to a variable called %URL%, which is one of a few environmental variables WebPageTest offers that refers to the URL you typed into the initial form field in the test. That'll make WebPageTest load spotify's start page.

The second execAndWait command says to execute some JavaScript on that page and keep recording until the scripting finishes executing. In this example, I've used a JavaScript that finds the first HTML element with a class of "your-selector-here" and clicks it.

In Spotify's page, I'll need a real selector for the link I want WebPageTest to click, so I used my browser's devtools inspector to look at their source code and find a selector that makes sense to click. The grid items shown here contain links that sit inside a div with an attribute of data-testid="grid-container":

screenshot of spotifys page with a web inspector panel finding the right element in the DOM

This selector should work fine to use as a parent selector for the element I want to click:

navigate %URL%
execAndWait	document.querySelector('[data-testid="grid-container"] a').click();

That script will cause WebPageTest to click the first link that happens to be in that grid when I run the test.

Lastly, I want to instruct WebPageTest to only record during the second navigation and not the first. Then I can capture timing that is specific to just that transition. I can do this using the logData command. logData 0 tells WebPageTest to stop listening while I run a command or two. logData 1 tells it to start recording again.

I'll use logData to isolate my recording to the second step here:

screenshot of the script tab with the script text below entered in the field

In text, here's that script in full:

logData 0
navigate %URL%
logData 1
execAndWait document.querySelector('[data-testid="grid-container"] a').click();

That's it! To run the test, just hit that Start Test button!

Viewing the Test Results

When WebPageTest finishes, it'll show a result like this:

screenshot of a webpagetest result page

And as you can see in the filmstrip below, WebPageTest has captured the session between the homepage and the playlist page it navigated to.

filmstrip showing a first frame of the homepage and a bunch of loading frames before the eventual second page

So there we go, these results show that Spotify took 1.9 seconds to complete a navigation from one previously-loaded page to another.

As for the reported metrics however, it's important to note that some are more relevant than others.

Many metrics come from the browser instead of WebPageTest itself, and those metrics are recorded from the start page, making them unhelpful in this type of test. For example, Core Web Vitals metrics are not relevant in this kind of test because they are measured by Chrome rather than by WebPageTest, and Chrome doesn't stop recording with logData commands like our own metrics do. Other metrics fall into this group as well, such as first contentful paint.

In addition to the filmstrip visual, the metrics you may find most helpful in this comparison are:

  • Time to First Byte
  • Start Render
  • Total Time
  • Total Bytes
  • Total Requests

Enjoy!

We've barely scratched the surface here with scripted tests, but hopefully this will give you a starting point for measuring those navigations after page load. From here, you might try combining logData with more complex scripts exported from the new WebPageTest Chrome Recorder Extension.

And since you're here, maybe check out this post about measuring and improving those web apps' initial loading speed as well! Cheers.

This is some text inside of a div block.

You might also like

Blog post

From refresh to results: the metrics that shaped Election Day 2024 coverage

Blog post

Did Delta's slow web performance signal trouble before CrowdStrike?

Blog post

Web Performance Experts Look into the Future of Web Performance