Stop ‘Snail-Paced’ Code with Lighthouse CI and GitHub Actions

Development tutorial - IT technology blog
Development tutorial - IT technology blog

Real Story: A 50k-Line Codebase and a Free-Falling Performance Score

I once managed an e-commerce project with over 50,000 lines of code. Initially, everything was under control, with Lighthouse scores consistently at 90+. However, after a refactor and adding a few tracking scripts from the Marketing team, the Performance score plummeted to 40. Even worse, the keyword rankings on Google Search Console fell into a tailspin shortly after.

My mistake at the time was relying too much on the “it works fast on my machine” feeling. In reality, web performance needs to be quantified. You must check it continuously in the CI/CD pipeline, just like how we write Unit Tests.

3 Silent Killers of Website Speed

Across many projects, I’ve noticed that scores usually decline for three typical reasons:

  • Bloated Libraries: A developer accidentally installed Moment.js (about 280KB) just to format a single date string, whereas dayjs only takes 2KB.
  • Unoptimized Images: The content team uploaded a 5MB banner image directly to the CMS instead of using a 200KB WebP format.
  • Render-blocking Scripts: Incorrectly placed tracking codes caused the browser to take an extra 2-3 seconds just to display the first frame.

If you only use Lighthouse manually in Chrome DevTools, it’s easy to miss errors. When working in a team, someone accidentally committing code that breaks Core Web Vitals is a common occurrence.

Why Lighthouse CI (LHCI) is the Perfect Choice

Before deciding on LHCI, I tried several other methods, but they all had drawbacks:

  1. Manual Checks: Opening Chrome and clicking Generate Report. This is extremely time-consuming and easy to forget.
  2. Using PageSpeed Insights API: Writing a script for periodic scans. However, it only reports after the code is already in Production. By then, the damage is already done.
  3. Lighthouse CI: This is a proactive solution. It stops bad code right at the gate (Pull Request). If the minimum score isn’t met, GitHub won’t allow the code to be merged.

Guide to Integrating LHCI into GitHub Actions

To get started, you need a web project pushed to GitHub. This process applies to React, Next.js, Vue, or even static HTML sites.

Step 1: Install the CLI

Install the Lighthouse CLI package in your project to test it in your local environment first.

npm install -g @lhci/[email protected]

Step 2: Set the “Rules of the Game” with lighthouserc.js

Create a lighthouserc.js file in the root directory. This is where you define the standards that new code must pass.

module.exports = {
  ci: {
    collect: {
      numberOfRuns: 3, // Run 3 times to get an average result and avoid variance
      staticDistDir: './dist', 
    },
    assert: {
      assertions: {
        'categories:performance': ['warn', { minScore: 0.9 }], 
        'categories:accessibility': ['error', { minScore: 0.8 }], 
        'categories:best-practices': ['error', { minScore: 0.9 }],
        'categories:seo': ['error', { minScore: 0.9 }],
        'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }], // Prevent layout shift issues
      },
    },
    upload: {
      target: 'temporary-public-storage', 
    },
  },
};

Step 3: Automate with GitHub Actions

Create the .github/workflows/lighthouse.yml file. GitHub will automatically run this script every time someone pushes code.

name: Lighthouse CI
on: [push, pull_request]
jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm install && npm run build
      - name: Run Lighthouse CI
        run: |
          npm install -g @lhci/[email protected]
          lhci autorun
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

Practical Experience: Don’t Be Obsessed with a Perfect 100

Many newcomers are often obsessed with getting a perfect score. In reality, GitHub’s CI servers (usually Ubuntu) have lower specs than a personal machine. Therefore, scores on CI are typically 5-10 points lower.

Instead of aiming for 100, focus on stability. If your project’s average score is 85, set the assertion threshold at 80. If a commit drops the score to 60, the system will “scream” immediately. This could be due to a new 2MB PNG image or a strange script blocking the main thread.

Conclusion

Setting up Lighthouse CI only takes about 20 minutes, but the long-term benefits are immense. It acts like a diligent gatekeeper, ensuring the user experience doesn’t degrade over time. Don’t wait until your SEO rankings drop to start optimizing. Integrate LHCI today to sleep soundly after every Merge.

Share: