Lighthouse Performance Audits: Scores, Metrics, | OpsBlu Docs

Lighthouse Performance Audits: Scores, Metrics,

How Google Lighthouse calculates performance scores, what each Core Web Vital means, and how to fix the most common performance issues it flags.

What Lighthouse Measures

Google Lighthouse is an open-source tool built into Chrome DevTools that audits web page performance, accessibility, SEO, and best practices. The performance score (0–100) is a weighted composite of six metrics:

Metric Weight What It Measures Good Threshold
First Contentful Paint (FCP) 10% Time until first text/image renders < 1.8s
Largest Contentful Paint (LCP) 25% Time until largest visible element renders < 2.5s
Total Blocking Time (TBT) 30% Sum of long task blocking time (>50ms each) < 200ms
Cumulative Layout Shift (CLS) 25% Visual stability — unexpected layout shifts < 0.1
Speed Index (SI) 10% How quickly visible content populates < 3.4s

TBT and LCP together account for 55% of the score — these are where most optimization effort should focus.

Running Lighthouse

Chrome DevTools: F12 → Lighthouse tab → select "Performance" → Analyze page load. Use incognito mode to avoid extension interference.

CLI (for CI/CD):

npm install -g lighthouse

# Basic run
lighthouse https://your-site.com --output=json --output-path=./report.json

# Emulate mobile (default) or desktop
lighthouse https://your-site.com --preset=desktop

# Run only performance category
lighthouse https://your-site.com --only-categories=performance

PageSpeed Insights: pagespeed.web.dev runs Lighthouse and also shows field data from the Chrome User Experience Report (CrUX) — real user measurements, not lab simulations.

Important: Lighthouse lab scores vary between runs (±5 points) due to network conditions and CPU throttling simulation. Run 3–5 times and use the median. Field data from CrUX is more reliable for tracking trends.

Fixing Common Performance Issues

Largest Contentful Paint (LCP) — 25% of Score

The LCP element is usually the hero image, main heading, or largest above-the-fold block.

Top causes and fixes:

<!-- Problem: Hero image loaded lazily (delays LCP) -->
<img src="hero.jpg" loading="lazy">

<!-- Fix: Remove lazy loading from above-the-fold images -->
<img src="hero.jpg" fetchpriority="high">

<!-- Fix: Preload LCP image in <head> -->
<link rel="preload" as="image" href="hero.jpg" fetchpriority="high">

Total Blocking Time (TBT) — 30% of Score

TBT measures how long the main thread is blocked by JavaScript tasks exceeding 50ms. This directly impacts interactivity.

Top causes and fixes:

// Problem: One massive JS bundle blocks the main thread
<script src="app.bundle.js"></script>  // 500KB, parsed in one long task

// Fix: Code-split and load only what's needed
<script type="module" src="critical.js"></script>
<script type="module" src="deferred.js" async></script>
  • Third-party scripts: Analytics tags, chat widgets, and ad scripts are the biggest TBT contributors. Audit with Chrome DevTools → Performance → Bottom-Up → Group by Third Party.
  • Hydration cost (React/Next.js): Server-render critical content and defer hydration of below-the-fold components.
  • Large DOM size: Pages with 1,500+ DOM nodes slow parsing and layout. Simplify component trees and remove hidden elements.

Cumulative Layout Shift (CLS) — 25% of Score

CLS penalizes unexpected visual movement after initial render.

<!-- Problem: Image without dimensions causes layout shift -->
<img src="photo.jpg">

<!-- Fix: Always set width and height (browser reserves space) -->
<img src="photo.jpg" width="800" height="600">

<!-- Fix: CSS aspect-ratio for responsive images -->
<style>
img { aspect-ratio: 4/3; width: 100%; height: auto; }
</style>
  • Web fonts: Use font-display: swap with size-adjusted fallbacks, or font-display: optional to eliminate flash entirely.
  • Dynamic content injection: Ads, banners, and cookie consent widgets that push content down. Reserve space with min-height on containers.
  • Late-loading CSS: Inline critical styles or preload stylesheet with <link rel="preload" as="style">.

Score Ranges and What They Mean

Score Rating What It Signals
90–100 Good (green) Meets Core Web Vitals thresholds; no major issues
50–89 Needs Improvement (orange) Some metrics failing; optimization opportunities exist
0–49 Poor (red) Significant performance problems affecting user experience

For SEO: Google uses Core Web Vitals (LCP, CLS, INP) as a ranking signal. Pages that fail CWV can lose ranking to competitors with equivalent content but better performance. The ranking impact is a tiebreaker, not a dominant factor — content relevance still matters most.

Lighthouse in CI/CD

Prevent performance regressions by running Lighthouse on every deploy:

# Lighthouse CI — set performance budgets
npm install -g @lhci/cli

# .lighthouserc.json
{
  "ci": {
    "assert": {
      "assertions": {
        "categories:performance": ["error", { "minScore": 0.8 }],
        "first-contentful-paint": ["warn", { "maxNumericValue": 2000 }],
        "largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
        "cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
        "total-blocking-time": ["error", { "maxNumericValue": 300 }]
      }
    }
  }
}

# Run in CI
lhci autorun --collect.url=https://staging.your-site.com

This fails the build if LCP exceeds 2.5s or CLS exceeds 0.1 — catching regressions before production.

Lab vs Field Data

Lab Data (Lighthouse) Field Data (CrUX)
Source Simulated on controlled device Real Chrome users over 28 days
Consistency Varies ±5 points per run Stable (large sample)
Metric TBT (lab proxy for interactivity) INP (real user interactivity)
Use for Debugging specific issues Tracking real user experience
Where DevTools, CLI, PageSpeed Insights PageSpeed Insights, Search Console

Lighthouse measures TBT as a lab proxy for responsiveness. In the field, Google uses Interaction to Next Paint (INP) instead — which measures actual user interaction latency. A page can score well in Lighthouse TBT but fail INP if JavaScript blocks specific interactions that lab tests don't trigger.

What OpsBlu Tests

OpsBlu's Phase 6 Lighthouse audit runs headless Chrome against each discovered site, capturing all six performance metrics plus accessibility, SEO, and best practices scores. Results are stored per-domain and surfaced in the audit dashboard with specific fix recommendations for each failing metric.

Next Steps