Fail PRs on Degraded Web Vitals with Lighthouse CI
Web development teams use Lighthouse CI (LHCI) to automate performance testing within continuous integration pipelines, ensuring code changes meet strict Core Web Vitals benchmarks before reaching production. By defining numeric thresholds for critical metrics like Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Total Blocking Time (TBT), teams can configure LHCI to flag regressions and automatically block pull requests (PRs) from merging through branch protection rules.
Configuring Lighthouse CI Assertions
The core mechanism for failing a pull request lies in the Lighthouse
CI configuration file, typically named lighthouserc.js or
lighthouserc.json. Within this file, teams define an
assert preset or individual assertion rules mapped to
specific metrics.
Instead of relying solely on an overall performance score, teams target specific audit keys corresponding to Core Web Vitals:
{
"ci": {
"assert": {
"assertions": {
"largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
"cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
"total-blocking-time": ["error", { "maxNumericValue": 200 }],
"categories:performance": ["error", { "minScore": 0.9 }]
}
}
}
}By setting the severity level to "error", LHCI exits
with a non-zero exit code if a build exceeds the defined
maxNumericValue or drops below the minScore.
Setting a rule to "warn" displays a warning message in the
build log but allows the CI step to pass, making "error"
the mandatory level for blocking PRs.
Running Audits in the CI Pipeline
Teams execute LHCI within their CI workflow (such as GitHub Actions, GitLab CI, or CircleCI) after building the application. A standard pipeline step involves:
- Building the production application assets.
- Starting a local or preview server to host the static or server-rendered pages.
- Executing the
lhci autoruncommand.
To reduce variance and false positives caused by network jitter or
temporary CPU throttling on shared CI runners, teams configure the
collect block to run multiple iterations:
{
"ci": {
"collect": {
"numberOfRuns": 3,
"startServerCommand": "npm run start",
"url": ["http://localhost:3000/"]
}
}
}Lighthouse CI evaluates the aggregated or median results against the assertions, providing a more stable evaluation of whether the code changes represent a true regression.
Integrating with Git Status Checks and Branch Protection
When lhci autorun completes, it evaluates all
assertions. If any assertion set to "error" fails:
- The Lighthouse CI process terminates with exit code 1.
- The CI job status transitions to "Failed."
- The CI platform sends a failure status back to the repository's pull request.
Engineering teams enforce this behavior by enabling branch protection
rules on target branches (like main or
production). By marking the Lighthouse CI workflow job as a
"Required Status Check," the repository host explicitly disables the
merge button until the performance checks pass.
Reporting Results Directly on the PR
To give developers immediate context on why a check failed, teams integrate an LHCI server or third-party GitHub Actions that post a comment directly to the pull request. This comment highlights exactly which Core Web Vital regressed, the measured difference between the base branch and the PR branch, and a link to the full Lighthouse report artifact to facilitate rapid debugging.