Ensure your Next.js app's performance is top-notch with Lighthouse CI and GitHub Actions
Tags: webdev, performance, nextjs, github
Published: 2023-01-03 18:18:04

Web performance is a crucial aspect of modern web development, yet I find that many developers do not prioritize it during development. This often leads to a backlog of performance optimizations that must be addressed just before a project is launched. In this article, I will demonstrate how to use Google Lighthouse to ensure performance in a GitHub CI workflow for a Next.js project.

**`TLDR;`** I use [the Google Chrome Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci) with a `.lighthouserc` json configuration to test `next start`. The Lighthouse CI GitHub app is used to return a pass or fail status check in a PR.

## Lighthouse CI configuration
Google has already created a great tool for using Lighthouse during CI called [the Google Chrome Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci). It offers great support for various applications. 

First of all we install the `lhci` package with `npm i --save-dev @lhci/cli`. This will be of great use when testing our Lighthouse configuration.
Since we need the Next.js server to run our application we cannot use the default Lighthouse configuration, which runs with `lhci autorun`, and will look for `.html` files in common static build folders.
Instead we use the following Lighthouse configuration which needs to be stored as `.lighthouserc` under the root of your project.


```json
{
    "ci": {
        "collect": {
            "startServerCommand": "npm run start",
            "startServerReadyPattern": "ready on",
            "url": [
                "http://localhost:3000"
            ],
            "numberOfRuns": 1,
            "settings": {
                "preset": "desktop"
            }
        },
        "assert": {
            "preset": "lighthouse:recommended"
        },
        "upload": {
            "target": "temporary-public-storage"
        },
        "server": {}
    }
}
```


This configuration tells Lighthouse to use `npm run start` and wait for the `ready on` output from the Next.js server. It will then start Chrome and perform a Lighthouse audit on the specified URL (in this case, `http://localhost:3000`, because the Next.js application is running on port 3000). You can configure multiple URLs, but for this example we will only use one. The number of runs can be modified, but we will stick with one run for this example. The more runs you configure, the longer the overall audit will take. In this example, we are using the desktop preset settings to emulate a standard desktop and use the recommended audit standards.

Give it a try by running `npx lhci collect`. Note that it creates a new `.lighthouseci` folder which contains the report.

## Integrate Lighthouse CI with GitHub actions
Now that we have Lighthouse set up and running in our local environment, we want to use GitHub actions to run Lighthouse checks every time we push a new commit. To do this, we will use [the Lighthouse CI app from the GitHub marketplace](https://github.com/apps/lighthouse-ci). This app will post the results of the Lighthouse audit to our pull request. To use it, enable the app in your organization or account and save the `LHCI_GITHUB_APP_TOKEN` as a secret in your GitHub repository.

`Repository > Settings > Secrets > Actions`

We will now create a GitHub action to run Lighthouse CI every time a new commit is pushed. To do this, create a file called `.github/workflows/lighthouseci.yml` under the root of your project with the following configuration:

```yml
name: CI
on: [push]
jobs:
  lighthouseci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: 16
      - run: npm install && npm install -g @lhci/cli@0.8.x
      - run: npm run build
      - run: lhci collect
      - run: lhci upload
        env:
            LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
```

This action will run `npm install` and `npm run build` every time a new commit is pushed. It will then execute Lighthouse and upload the results. Because we added the `LHCI_GITHUB_APP_TOKEN`, the results will be attached as new status checks and will pass or fail based on the assert configuration in `.lighthouserc`.

![Lighthouse results displayed in a Pull request on GitHub](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jv9k8t9wwqwyd3dirhd6.jpg)

When we click at the right side on the details link, we will get the full Lighthouse report for this commit. This report allows us to inspect every detail, just like when we perform an audit in a tool like DevTools.

![Top part of a full Lighthouse report](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s388gx6aefdh21e2fqat.jpg)

Thank you for reading my article. I hope it was helpful for your development workflow. If you found it valuable, please consider liking it. It would mean a lot.