DEV Community

Cover image for Continuous performance audits in Nuxt with Lighthouse CI and Github Actions
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

Continuous performance audits in Nuxt with Lighthouse CI and Github Actions

Performance is an area in software development that is important no matter what application you are building. Delivering a great experience to users is crucial for having a great software product, and performance is one of the key values of it.

If you are interested into learning more about what you can do to improve performance of your website, check out my other article here which is in a form of a useful checklist.

These recommendations should increase the performance of your application but to make sure that these any other future site features will improve the performance you have to constantly measure it.

For this tutorial I will be using Nuxt 3, Lighthouse CI, and Github Actions but you can adjust it to your code repository workflows.

Code

We will create a simple Nuxt app with below command:



npx nuxi init <project-name>


Enter fullscreen mode Exit fullscreen mode

Navigate to your project, run it, and check if everything is working as expected:



cd <project-name>
yarn dev


Enter fullscreen mode Exit fullscreen mode

When the project will start, this should be the result in your browser.

Nuxt Homepage

Lighthouse

You will need to install and authorise the Lighthouse CI application for Github. Make sure to copy the generated LHCI_GITHUB_APP_TOKEN as we will need it later.
https://github.com/apps/lighthouse-ci

Github Lighthouse authorisation

After authorisation you should see a page like this:

Github Lighthouse authorisation with token

Install @lhci/cli package



yarn add -D @lhci/cli


Enter fullscreen mode Exit fullscreen mode

Add Lighthouse CI commands to your package.json (for CI and local testing)



// package.json

...
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "start": "nuxt preview"
    "lhci:mobile": "lhci autorun",
    "lhci:desktop": "lhci autorun --collect.settings.preset=desktop"
  },


Enter fullscreen mode Exit fullscreen mode

Create lighthouserc.json with configuration for Lighthouse CI



// lighthouserc.json

{
  "ci": {
    "collect": {
      "startServerCommand": "yarn build && yarn start",
      "url": ["http://localhost:3000/"],
      "numberOfRuns": 3
    },
    "upload": {
      "target": "temporary-public-storage"
    }
  }
}


Enter fullscreen mode Exit fullscreen mode

Let's stop for a second here to explain how we are configuring the lighthouse to conduct audits.

collect:

  • startServerCommand - a command that we want Lighthouse to use in order to start testing. In our case we will build our Nuxt project for production and start it.
  • url - An url address that we want Lighthouse to conduct audits on. For the sake of this tutorial we will be using http://localhost:3000/ to test just the homepage but you can also setup other routes here like http://localhost:3000/categories
  • numberOfRuns - A number that defines how many times Lighthouse should test the selected url and create a median out of these results.

upload:

  • target - where do we want to upload the result of our Lighthouse audit report. By default is set to temporary- public-storage

Test if the Lighthouse audit is working as expected



yarn lhci:desktop


Enter fullscreen mode Exit fullscreen mode

The command should log following result:

Nuxt Lighthouse result

And when we visit the link that was created by Lighthouse in the terminal we should see something like this:

Nuxt Lighthouse report

Well done! Now you have successfully conducted Lighthouse audit locally. As our final step, we will create a Github workflow to run Lighthouse CI on every pull request to main branch.



name: CI
on:
  pull_request:
    branches:
      - main
jobs:
  lighthouse:
    name: Lighthouse CI
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          ref: ${{ github.event.pull_request.head.sha }}

      - name: Install dependencies
        run: yarn

      - name: lighthouse mobile audit
        run: yarn lhci:mobile
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

      - name: lighthouse desktop audit
        run: yarn lhci:desktop
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}


Enter fullscreen mode Exit fullscreen mode

Now, whenever we create a pull request to main branch with this workflow implemented we will automatically trigger a Github Action that will be conducting Lighthouse audits.

Remember the step about authorising Lighthouse application for Github? If you do not have a secret in your repository you would still be able to trigger Github Action but you will not get a nice looking status check from Lighthouse with all metrics. No worries, you would still be able to see the report but you would have to go to the details of the action and go to the link directly.

Lighthouse Github Action

When we add a token in repository settings it should be visible like this:

Github secrets for Lighthouse

To confirm that we did all steps correctly we should see a status report from Lighthouse directly in the pull Github Actions output of a pull request

Lighthouse Github report status

** Keep in mind that the status report from Lighthouse application for Github will provide only one status report even though we have done two tests (for desktop and mobile devices) so you would have to check the second report manually. If you have found a way to display multiple status reports please let me know in the comments and I will update the article accordingly :)

Summary

You have successfully implemented Lighthouse CI auditing that can be triggered both locally and as a Github Action.

This approach would suit most of the cases however to achieve more accurate performance audits you should be conducting Lighthouse tests on a dedicated server to avoid results being affected by the machine capabilities. In other words, if you are running Lighthouse audits on a repository where there are several pull requests/workflows/pushes going on, the result of this audit may not be accurate and this is what we want to avoid. For that you would need a separate machine with Lighthouse Server installed on it. So on a pull request you would trigger this machine to conduct a performance audit and return response to your repository.

Bonus: Using Github Action instead of npm package

Instead of using npm package you could use a Github Action that would esentially do the same thing but wi. The downside to that approach is that you won't be able to test your project locally with lighthouse (unless you are using local github actions package like https://github.com/nektos/act)



name: CI
on: 
  pull_request:
    branches:
      - main
jobs:
  lighthouse:
    runs-on: ubuntu-latest
    needs: deploy
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          ref: ${{ github.event.pull_request.head.sha }}

      - name: Install dependencies
        run: yarn

      - name: Build and start the project
        run: yarn build && yarn start

      - uses: actions/checkout@v2
      - name: Audit URLs using Lighthouse
        uses: treosh/lighthouse-ci-action@v7
        with:
          urls: http://localhost:3000
          uploadArtifacts: true # save results as an action artifacts
          temporaryPublicStorage: true # upload lighthouse audits to google temporary storage


Enter fullscreen mode Exit fullscreen mode

Top comments (4)

Collapse
 
pixeliner profile image
Pixeliner

Hi, an amazing article as usual.

I've been following you for a while now. I've been learning quite some NestJs and Next/Nuxt. I found your excellent otasoft open source project and learned so much out of it. I noticed though your frontend projects for it are just initial setups. I was wondering if you could maybe explain what the best approach would be in NextJs if I wanted to authenticate with the NestJs backend and it's token cookies?

Maybe an idea for a next post? :)

Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Hey, thank you for the kind words!

I really appreciate it!

Regarding, next.js, I am afraid that I dont have that much knowledge there as I am a primarly a Nuxt developer but I can definitely point you to the right direction. For the next.js part, I would recommend next-auth.js.org/ and for the nest.js part, go for passport plugin -> docs.nestjs.com/security/authentic....

I have been thinking to actually tackle a concept of authentication in Nuxt with the usage of nuxt-auth, but coming back to Nest would be refreshing. Thanks for the idea!

Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Also, if you would like some cool materials on Next.js, I would love to recommend @colbyfayock. He is a great content creator.

While for Nest.js I really like this blog wanago.io/

Thread Thread
 
colbyfayock profile image
Colby Fayock

thanks for the shoutout! have a lot of videos you can find over here:

youtube.com/colbyfayock

and written tutorials over here:

spacejelly.dev/categories/next-js/