DEV Community

Cover image for Getting Started with Lighthouse User Flows
Maxi Ferreira
Maxi Ferreira

Posted on • Edited on

Getting Started with Lighthouse User Flows

The Google Chrome Team recently announced two big features coming to Lighthouse 9.0 and Chrome DevTools: User Flow Reports in Lighthouse, and a new Recorder panel in DevTools that can capture and replay user journeys with just a few clicks.

I've been experimenting with both of these tools for the past couple of weeks, and I've been genuinely impressed by how powerful they are and the possibilities they bring when you use them together.

In this post, I want to share a quick overview of what these features are and how they work, and finally walk you through an example that combines them to unlock their full potential. Let's dive in!


Lighthouse User Flow Reports

Unlike traditional Lighthouse reports (which only audit a website during its initial page-load), user flow reports can analyze a page at any point during its life-cycle. We can take "snapshots" of a page at a particular moment, or even collect metrics over a period of time that includes user interactions.

User flows are available as a new API in the Lighthouse Node module, and we can use them alongside tools like Puppeteer which allow us to control the browser and trigger synthetic events programmatically.

Here's an example of how we can generate a user flow report using Puppeteer and the Lighthouse API (you can see the complete code here).

async function captureReport() {
  // Puppeteer initialization
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // Start user flow
  const flow = await lighthouse.startFlow(page, { name: 'My User Flow' });

  // ... Caputure reports here ...

  // End user flow
  return flow.generateReport();
}
Enter fullscreen mode Exit fullscreen mode

Within a user flow, there are three types of reports that we can capture:

  • Navigations – to audit cold and warm page-loads,
  • Snapshots – to audit the exact state of the page at any point in time, and
  • Timespans – to audit a page during any period of time.

We're going to see concrete examples of each one of them in the last section, but here's a quick overview of what they do and how their APIs look like.

Navigation Report Diagram

Navigations

These are the standard Lighthouse reports that audit a page during page-load, except that now we can measure both cold page-loads (clearing caches and local storage), and warm page-loads (without clearing the cache). We can even capture multiple navigation reports as part of the same user flow report see how they compare.

This is how we can capture a navigation report with this new API:

await flow.navigate('https://www.nytimes.com')
Enter fullscreen mode Exit fullscreen mode

We can also give the report a descriptive name with the stepName option:

await flow.navigate('https://www.nytimes.com', {
    stepName: 'Cold navigation'
})
Enter fullscreen mode Exit fullscreen mode

And we can capture a warm load by setting the disableStorageReset flag:

await flow.navigate('https://www.nytimes.com', {
    stepName: 'Warm navigation',
    configContext: {
        settingsOverrides: { disableStorageReset: true },
    }
})
Enter fullscreen mode Exit fullscreen mode

Snapshot Report Diagram

Snapshots

We can take a snapshot at any point during the user flow, and Lighthouse will analyze the page in its exact state. This is useful for when we want to audit a particular state of the UI that only appears after a user interaction – like a modal that shows up when the user clicks a button.

await flow.snapshot({ stepName: 'Checkout modal opened' });
Enter fullscreen mode Exit fullscreen mode

Since we're only analyzing a single moment and not a period of time, the metrics in the snapshot report are not terribly useful for performance, but they're a great way to get accessibility and best practices insights based on the state of the page after the user interacts with it, which is something that wasn't possible before.

Timespan Report Diagram

Timestamps

These reports audit a website over a period of time, which can contain user interactions as well. From a performance perspective, they're useful to measure Total Blocking Time (TBT) and Cumulative Layout Shift (CLS) while a user interacts with a page.


await flow.startTimespan({ stepName: 'Checkout flow' });

// ... user interactions here ...

await flow.endTimespan();

Enter fullscreen mode Exit fullscreen mode

Measuring CLS beyond the initial page is particularly useful because it gives us a more accurate measure of this metric in the lab, that is closer to what we'll see in our field data.


For a much more detailed overview of Lighthouse user flows with complete code examples, I highly recommend checking out the official tutorial on web.dev.

User Flow Reports Explained


Chrome DevTools Recorder Panel

The Recorder panel is a new feature coming to Chrome DevTools (currently available in Chrome 97), which allow us to record and replay user journeys with just a few clicks.

Chrome DevTools Recorder Panel

At the time of writing, the Recorder panel is only available in the Chrome Dev and Canary builds, so make sure you have one of those installed if you'd like to follow along.

You can find the Recorder panel in DevTools under More options > More tools > Recorder, or by opening the Command Menu (with Cmd + Shift + P) and searching for Recorder.

Recorder How To Find It

With the Recorder panel opened, you can click the Start new recording button, give the recording a name, and start interacting with the page in any way you want (for example, completing an sign up or checkout flow). Once you're done with the recording, you'll be able to replay it, modify it, run a performance profile for the entire journey, or export the recording as a Puppeteer script.

This last feature is what we're mostly interested in. We can use the auto-generated Puppeteer script as a starting point for creating user flow reports with Lighthouse, which will save us a ton of time and effort. We'll explore this approach next.


Lighthouse Reports on User Journeys

Now that we've seen what Lighthouse user flow reports are and how we can record user journeys and export them as Puppeteer scripts with the DevTools Recorder panel, let's explore how we can use them together to capture a user flow report based on a user journey.

The process is simple: we'll record a user journey in DevTools, export it as a Puppeteer script, and we'll modify the script by adding a few calls to the Lighthouse user flow APIs in the right places. In the end, we'll be able to run the script with Node.js and get shiny new User Flow Report back.

1. Project setup

The first thing we need to do is initialize a new npm project (ideally in a new folder) and install the dependencies we're going to be using:

mkdir lighthouse-reports
cd lighthouse-reports
npm init -y
npm install lighthouse puppeteer open --save
Enter fullscreen mode Exit fullscreen mode

We'll use the open package so that we can automatically open the HTML report in the browser once the script finishes, but this is an optional dependency (and you definitely don't need it if your running the script in CI).

2. Record and export a user journey

For this tutorial, I'm going to use this coffee shopping demo app (borrowed from Google's documentation) to record a simple user journey: adding a couple of items to the cart, navigating to the shopping cart, and going through the (fake) checkout process.

I encourage you to do something similar to keep things simple, but you can of course use any website you want and go wild with your user journey. Simply hit the "Start recording" button on the Recorder panel and start interacting with the page by clicking around, scrolling, or filling out forms. Make sure you stop the recording once you're done.

Example Recording Animation

Once you've finished recording, make sure you can replay it by hitting the Replay button on the top right. This is important. If the flow can't be replayed consistently, you might run into issues generating the Lighthouse reports later on.

For more details on how to use the Recorder panel, check you this great article in the Chrome DevTools documentation site.

Once you're happy with your recording, export the user flow as a Puppeteer script by clicking the Export icon on the top (be careful not to click the delete icon by mistake, they're dangerously close together!), and save it in the project folder as user-flow.js.

3. Edit the script

Now comes the fun part. If you open the user-flow.js script, you'll find that it consists of a bunch of utility functions at the top, followed by a series of code blocks, each one representing a "step" in our user journey (clicks, scrolls, keyboard events, etc.)

We're going to make a few modifications to this script to generate a Lighthouse user flow report consisting of four "sub-reports":

  • Two navigation reports (to measure both cold and warm page-loads),
  • A snapshot report to capture the state of the page when the checkout modal is open, and
  • A timespan report to capture the entire checkout flow.

You might find it easier to see the modifications to the script in this annotated file or in this diff, but if you prefer a step-by-step guide, just read on and code along!

3.1 Import dependencies

First off, let's import the rest of our dependencies right after the puppeteer require in the first line:

const open = require('open');
const fs = require('fs');
const lighthouse = require('lighthouse/lighthouse-core/fraggle-rock/api.js');
Enter fullscreen mode Exit fullscreen mode

3.2 Create the user flow

Right at the top of the script's main function, you'll find a couple of lines that create the Puppeteer browser and page instances. We'll create our user flow instance right after that:

const flow = await lighthouse.startFlow(page, { name: 'My User Flow' });
Enter fullscreen mode Exit fullscreen mode

3.3 Add the Navigation reports

Now we need to scroll down to where the code blocks start. We'll add the two navigation reports right after the block with the targetPage.goto('https://coffee-cart.netlify.app/') call:

// Cold navigation report
{
  const targetPage = page;
  await flow.navigate('https://coffee-cart.netlify.app/', {
    stepName: 'Cold navigation'
  });
}

// Warm navigation report
{
  const targetPage = page;
  await flow.navigate('https://coffee-cart.netlify.app/', {
    stepName: 'Warm navigation',
    configContext: {
      settingsOverrides: { disableStorageReset: true },
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

3.4 Add the Snapshot report

You can add this call between any two steps in the script, but for demonstration purposes, we want to take the snapshot once the Checkout modal opens. Add the following code right after the code block with the waitForSelector call that waits for the "aria/Proceed to checkout" element:

{
  await flow.snapshot({ stepName: 'Checkout modal opened' });
}
Enter fullscreen mode Exit fullscreen mode

3.5 Add the Timespan report

We'll start the timespan right after the snapshot() call from the previous step:

{
  await flow.startTimespan({ stepName: 'Checkout flow' });
}
Enter fullscreen mode Exit fullscreen mode

And we'll end it at the end of the flow, right before the call to browser.close():

{
  await flow.endTimespan();
}
Enter fullscreen mode Exit fullscreen mode

3.6 Generate the user flow report

Finally, we need to generate the report, save it as an HTML file, and open it in the browser. Add the following lines right before the end of the main function (after the call to browser.close()):

const reportPath = __dirname + '/user-flow.report.html';
const report = flow.generateReport();
fs.writeFileSync(reportPath, report);
open(reportPath, { wait: false });
Enter fullscreen mode Exit fullscreen mode

And we're done! If you save and run the script (with node user-flow.js), you should see the report coming up on your browser after a few moments.

User Flow Report Screenshot

If you didn't follow the steps with me but would like to see how the report looks like, you can open the live report and play with it here. You'll see a timeline with our four reports in the order we captured them, and you can click in each one for a more detailed view. How cool is that?!

Final thoughts

Lighthouse user flows and the new DevTools Recorder panel are like milk and cookies: they're both amazing on their own, but they're definitely better together.

The new Lighthouse APIs enable new ways to measure the performance and accessibility of our websites, generating lab data that is more representative of what real users experience in the field. And with the auto-generated Puppeteer scripts, the process of capturing these data is a breeze.

The Recorder panel also has many interesting use cases in addition to measuring performance. We can use the Puppeteer scripts as a starting point for running automated end-to-end tests, or even use them directly as a quick way to assert that user journeys can be completed correctly. And of course, since these are just Node scripts, we can run them as an additional step in our CI pipelines.

Finally, I think it's important to keep in mind that these features are still quite young, so you may run into a few issues here and there (if you do, be sure to share your feedback with the Chrome team!). I still encourage you to give them a try and explore the cool things you can do with them.


Resources

  • For more information about Lighthouse user flow reports, check out the official tutorial on web.dev.
  • For detailed instructions about the DevTools Recorder panel, take a look at the official documentation on Chrome Developers.

I would love to hear your thoughts about this process if you give it a try! Please let me know in the comments, or reach out on Twitter.

Thank you for reading ❤️

Top comments (0)