Skip to content

Greg Jopa

Lighthouse Audits for Static Sites with GitHub Actions

Gatsby.js, Lighthouse, Continuous Integration

The project Lighthouse CI Action makes it easy to run Lighthouse Audits with GitHub Actions. The audit results can be used to enforce a performance budget for your website. For example, here's what a job failure looks like when the DOM Size and Time To Interactive (TTI) metrics exceed the performance budget:

Lighthouse assertion errors with GitHub Actions

In this post I'll explain how I set up a performance budget for my personal blog which is built with Gatsby.js.

GitHub Action Setup

The examples in the Lighthouse CI Action docs are a great way to learn what configurations are possible. I followed the static site recipe with a few tweaks.

Here's the job workflow I used for my Gatsby.js site:

  1. Check out the source branch
  2. Install npm dependencies
  3. Build the static site
  4. Run Lighthouse audits against the provided list of urls
  5. Run assertions to ensure no thresholds are exceeded

There are two specific settings I want to highlight:

  1. staticDistDir - Lighthouse CI supports running audits against static html files. It can spin up a web server and host these static files and run audits against them. To utilize this feature, I set up the job to run npm run build before the Lighthouse audit. I also updated the lighthouserc.json file to look for the static site in the public directory "staticDistDir": "./public".
  2. Multiple Runs - Some performance metrics in Lighthouse audits can be flaky. Thankfully there's an option to specify multiple runs and lighthouse-ci will magically take the averages. For example, I'm running three audits for each url with the runs: 3 option.

Here's my full configuration file:

1name: Lighthouse
2on:
3 push:
4 branches:
5 - source
6 pull_request:
7 branches:
8 - source
9jobs:
10 audit_urls:
11 runs-on: ubuntu-latest
12 strategy:
13 matrix:
14 node-version: [12.x]
15 steps:
16 - uses: actions/[email protected]
17 - name: Use Node.js ${{ matrix.node-version }}
18 uses: actions/setup-[email protected]
19 with:
20 node-version: ${{ matrix.node-version }}
21
22 # build the static site
23 - run: npm install
24 - run: npm run build --if-present
25 - name: Run Lighthouse against static public directory
26
27 # configure lighthouse
28 uses: treosh/lighthouse-ci-[email protected]
29 with:
30 uploadArtifacts: true
31 temporaryPublicStorage: true
32 runs: 3
33 configPath: '.github/workflows/lighthouserc.json'

Lighthouse Configuration

There are two options for configuring a performance budget with Lighthouse:

  1. budget.json - There's great work being done to standardize performance budgets across speed tools like Lighthouse and SpeedCurve. Check out the budget.json spec for more details.
  2. assertions in lighthouserc.json - You can specify assertions directly in the lighthouserc.json file. These assertions are specific to Lighthouse. I chose this option because I wanted to have assertions for the different lighthouse categories.

Here's my lighthouserc.json file with assertions:

1{
2 "ci": {
3 "collect": {
4 "url": [
5 "http://localhost/",
6 "http://localhost/2020/03/integrating-vexflow-with-gatsby-js"
7 ],
8 "staticDistDir": "./public"
9 },
10 "assert": {
11 "assertions": {
12 "categories:accessibility": ["error", { "minScore": 0.95 }],
13 "categories:best-practices": ["error", { "minScore": 0.9 }],
14 "categories:performance": ["error", { "minScore": 0.8 }],
15 "categories:seo": ["warn", { "minScore": 1 }],
16 "dom-size": ["error", {"maxNumericValue": 1000}],
17 "first-contentful-paint": ["error", {"maxNumericValue": 2000}],
18 "interactive": ["error", {"maxNumericValue": 5000}]
19 }
20 }
21 }
22}

The Lighthouse CI Assertions documentation goes into more detail about features like asserting on specific audits and urls.