What does a Lighthouse audit actually tell you, and which number do you act on? It loads one page on an emulated phone over a throttled connection, scores performance, accessibility, best practices and SEO from 0 to 100, and lists what failed. One run is a lab sample, so a Lighthouse audit worth keeping records the pages, the device profile, the targets and the median of five runs.

What Lighthouse is, and what the score measures

A Lighthouse audit is one controlled load of one page by Google’s open-source auditing tool, with Performance, Accessibility, Best Practices and SEO each scored from 0 to 100. The Performance score is a weighted average of 5 lab metrics, Total Blocking Time weighted most. It is a lab result, not what real visitors experienced.

Lighthouse is one of the checks behind web performance optimization, and its first rung needs nothing installed beyond Chrome.

Chrome’s Lighthouse overview calls it “an open-source, automated tool to help you improve the quality of web pages” and says you can run it “on any web page, public or requiring authentication”. It runs in Chrome DevTools, from the command line or as a Node module, and PageSpeed Insights runs it too, putting the Lighthouse lab result next to field data from real Chrome users when that data exists.

The current major version is Lighthouse 13; the project’s changelog lists 13.5.0, dated September 17, 2026, as the latest release. PageSpeed Insights runs it for four categories: Performance, Accessibility, Best Practices and SEO. Lighthouse 13.3.0 added a fifth, Agentic Browsing, to the default config, and the category’s own description says it “is still under development and subject to change”. The PWA category is gone: Lighthouse 12.0 removed it in April 2024, so there is no PWA audit or score left to chase.

CategoryWhat it checksHow it is scored
PerformanceFive lab metrics from one page load: First Contentful Paint, Speed Index, Largest Contentful Paint, Total Blocking Time and Cumulative Layout ShiftWeighted average of the five metric scores: FCP 10%, Speed Index 10%, LCP 25%, TBT 30%, CLS 25% (the Lighthouse 10 weights, unchanged in 13.5.0); each raw value is mapped to a score from 0 to 100 on a log-normal curve built from HTTP Archive data
AccessibilityWhat an automated check can decide: color contrast, form labels, names on buttons and links, ARIA attributesWeighted average of pass or fail audits, weights based on axe user impact; a page gets no points for passing an audit on only some of its elements
Best PracticesTrust and safety, user experience, browser compatibility and general checks such as HTTPS, deprecated APIs and console errorsWeighted average of its audits; HTTPS, deprecations and third-party cookies weigh 5, the rest 3, 1 or 0
SEO”basic search engine optimization advice”: crawlability, the title, the meta description, link text, image alt textWeighted average of its audits; the crawlability audit is weighted so that failing it fails the category
Agentic Browsing (13.3.0 and later)Whether AI agents can browse the page, and WebMCP integrationsDisplayed as a fraction; still under development

So when someone quotes a Lighthouse audit score, ask which category, which device profile and which run it came from. Scores are colored in three bands, in the docs’ words: 0 to 49 (red): Poor, 50 to 89 (orange): Needs Improvement, 90 to 100 (green): Good. Lighthouse performance scoring adds: “A ‘perfect’ score of 100 is extremely challenging to achieve and not expected.”

Two limits matter before you act on the number. It describes one simulated load in a controlled environment, not your users’ visits, and PageSpeed Insights notes that lab data “may not capture real-world bottlenecks”. And the SEO category is narrow by design; the report describes it as checks that the page “is following basic search engine optimization advice”.

Why two runs of the same page give two scores

Lighthouse scores change between runs because the network, the server, the test machine, browser extensions and page content such as ads and A/B tests all vary. The project’s guidance is to run it several times and use the median; by its own measure, the median of 5 runs is twice as stable as 1 run.

Lighthouse’s variability documentation lists seven sources: page nondeterminism (an A/B test or a different ad), local network, tier-1 network, web server, client hardware, client resource contention and the browser itself. It singles out “Malware, browser extensions, and anti-virus software” for having “particularly strong impacts on web performance”. Simulated throttling, the default, mitigates local network variability and partly mitigates hardware differences, but it offers no mitigation for a page that changes between runs or a server that answers slowly.

PageSpeed Insights runs Lighthouse on separate servers, which Chrome’s DevTools documentation says may produce cleaner, more consistent audits, and the same page warns that you “cannot directly compare two Lighthouse audits completed on different machines”. In my reading, a PageSpeed Insights score and a laptop’s DevTools score for the same URL will differ and neither is wrong: they come from two machines. Compare runs only within one setup.

What goes wrong without it

A low score on a new app is normal, and fixable. The trouble starts when a number measured the wrong way gets trusted. These six habits are the ones I’d rule out before anyone touches code:

What people doWhy it misleadsWhat to do instead
Report one desktop run as “the score”The desktop preset swaps in a desktop screen, a different throttling preset and, since Lighthouse 6, its own scoring curves; the docs say desktop scores “will be significantly different”Report the mobile profile; add desktop as a second column if you want it
Test only the landing pageThe pages customers live in (dashboard, list views, checkout) sit behind login and never get loadedPick three to five pages, including one behind login
Test the dev serverUnminified bundles and no compression produce a low Lighthouse performance score that says nothing about productionAudit the production build at its real URL
Leave extensions onExtensions that inject JavaScript or modify network requests do it inside the load being measuredUse an incognito window or a Chrome profile with no extensions
Chase 100Near the top the curve flattens: going from 99 to 100 “needs about the same amount of metric improvement that would take a 90 to 94”Write the target down before the work starts
Keep no recordA score in a chat message, with no version, profile or date, cannot be compared with next month’s, and the weights have changed between versionsKeep the run record described in the verify section

The version problem is not special to Lighthouse. Wikimedia’s Phabricator task T196242, opened June 2, 2018, records it in a synthetic test setup. After Chrome 67 was pushed to that setup, Speed Index and first visual change went up; rolling back to Chrome 66 meant “the metrics got back to normal”, and pushing 67 again repeated it. Wikimedia’s WebPageTest alerts stayed silent “because all pages aren’t affected”: of the five articles named, three regressed, one was unchanged and one rendered a little faster, and real-user data started alerting on June 11. The lesson I take from it: a lab number belongs to its browser, its tool version and its page list, so a Lighthouse number reported without them is not yet a measurement.

How to run a Lighthouse audit you can repeat

A repeatable Lighthouse run fixes five things: three to five named pages (my working rule) including one behind login, the default mobile device profile, the production build in a clean browser window, the Lighthouse version written down, and the median of 5 runs per page saved as JSON.

The steps below follow Chrome’s Lighthouse documentation and the Lighthouse project’s own documentation on throttling, variability and authenticated pages, as checked on October 4, 2026.

Choose the pages and the device profile

My working rule is three to five representative pages, not every URL: enough to cover the public side and the logged-in side without turning the audit into a crawl.

Page typeExampleWhy it is on the list
Landing page/The first load a new visitor sees; public, so PageSpeed Insights can run it too
Pricing or signup/pricing, /signupThe step between interest and an account
First screen after login/dashboardWhat every returning user waits for, and a page a default command-line run only sees as a logged-out “new user”
Heaviest list or dashboard view/projects, /ordersLong lists, tables and charts are where main-thread work piles up
Checkout, if the app takes money/checkoutThe step where a customer pays

The device profile is Lighthouse’s default mobile one: an emulated Moto G Power (412 by 823 pixels, device scale factor 1.75), simulated throttling to a connection Lighthouse calls “Slow 4G” (150 ms latency, 1.6 Mbps down and 750 Kbps up), and a 4x CPU slowdown. Mobile stays the reported profile. Desktop can be a second column on the record, never a replacement, because it is scored on its own curves.

Write down the Lighthouse version. The report prints it in the footer, in the line that reads “Emulated Moto G Power with Lighthouse” followed by the version, next to the capture time and the Chromium version. It matters because the weightings “have changed over time”: Lighthouse 8 still gave Time to Interactive 10% and CLS only 15%.

Run it in DevTools, PageSpeed Insights or the command line

Start in the browser. This is the whole run for one page, with nothing to install:

  1. 01 Open the production URL in a Chrome incognito window, or in a Chrome profile with no extensions.
  2. 02 For a page behind login, sign in first in that same window, then go to the page.
  3. 03 Open Chrome DevTools and click the Lighthouse tab.
  4. 04 Keep the default Navigation mode, set Device to Mobile and leave every category enabled.
  5. 05 If your login keeps its session in localStorage or IndexedDB, open the panel settings and uncheck Clear storage.
  6. 06 Click Analyze page load; the report arrives after 30 to 60 seconds.
  7. 07 Open the three-dot menu, save the report as JSON, and repeat the last two steps until the page has 5 runs.

Steps 2 and 5 come from the authenticated-pages documentation: the DevTools panel “will never clear your cookies, so you can log in to the target site and then run Lighthouse”, and Clear storage matters only when localStorage or IndexedDB carries the login. Chrome’s DevTools docs say running Lighthouse in incognito mode is often recommended, and warn that even then a run “may still be subject to these influences” from your machine.

PageSpeed Insights is the no-install route for public URLs: enter the URL, click Analyze, and the lab section is a Lighthouse run while the field section shows Chrome User Experience Report data when the page or the origin has enough of it. Unlike DevTools, it does not let you choose the device type or the categories.

The command line is the route for repeat runs. Lighthouse needs Node (the current LTS release) and Chrome installed, defaults to the mobile profile, and can write JSON and HTML from one run. The loop below runs one page five times, one run after another, because the variability documentation warns against collecting several reports at the same time on one machine.

npm install -g lighthouse
mkdir -p runs
for i in 1 2 3 4 5; do
  lighthouse https://app.example.com/pricing --output json --output html \
    --output-path ./runs/pricing-$i --quiet --chrome-flags="--headless"
done

Each run writes pricing-1.report.json and pricing-1.report.html, and so on up to 5. Sort the five performance scores and take the middle one; do the same for each metric, and record those medians for the page. If you would rather not do the sorting, the variability documentation names Lighthouse CI as the simplest way to run Lighthouse several times and get a median run. The Chrome extension exists too, but Chrome’s overview says to prefer DevTools, which can test local sites and authenticated pages while the extension cannot.

Set numeric targets before the first fix

Lighthouse targets are written before the first fix: each metric at its score-90 value on the mobile curve, category scores of 90 or above on public pages, and, by my working rule, accessibility at 100 on core pages. A dashboard far below that gets a written target with its reason, by my working rule too.

What is measuredTarget (mobile profile)Where the threshold comes from
Largest Contentful Paint2,500 ms or lessLighthouse 13.5.0 mobile scoring curve: the value that scores 90
Total Blocking Time200 ms or lessSame curve, score-90 point
Cumulative Layout Shift0.1 or lessSame curve, score-90 point
First Contentful Paint1,800 ms or lessSame curve, score-90 point
Speed Index3,387 ms or lessSame curve, score-90 point
Performance score, public pages90 or aboveThe docs’ green band, “Good”
Accessibility score, core pages100My working rule; it covers automated audits only
Performance score, logged-in dashboard far below 90Set from the baseline, written with its reasonMy working rule

Chrome’s scoring page describes the method: each metric’s curve has a good/green control point that becomes a score of 90, and it points to the Lighthouse scoring calculator for working out which metric values reach a given Performance score. The values in the table are those score-90 points as Lighthouse 13.5.0’s source code sets them for mobile. The accessibility target covers only what a machine can check; the keyboard walk and the full baseline belong to an accessibility audit.

My working rule for a logged-in dashboard that starts far below the green band: set the target from the baseline and write the reason next to it, for example “metric targets met on LCP and TBT, score recorded as it lands”. A target nobody wrote down is a target that moves. The acceptance line for the whole audit is one sentence long: pages, profile, version, targets, results, date. The field thresholds for Core Web Vitals are a different measure, and the lab and field section below points to them.

Keep it from sliding back with Lighthouse CI

Chrome’s overview offers Lighthouse CI “to prevent regressions on your sites”. The project calls it “a suite of tools that make continuously running, saving, retrieving, and asserting against Lighthouse results as easy as possible”. Its collect step runs Lighthouse 3 times per URL by default, and its assert step “exits with the appropriate status code if there were any failures”, which is what fails a build; a budget.json file can stand in for assertions. My working rule for a small team: one public URL, the run count raised to 5 to match the median rule, and two assertions, one on the performance category score and one on Largest Contentful Paint. Logged-in pages need extra setup, and the authenticated-pages documentation calls a Puppeteer-scripted login the most flexible approach, so treat them as optional. A bundle-size budget belongs with the JavaScript row in the next section.

How to improve Lighthouse score: what to fix first

A Lighthouse score improves fastest when fixes follow the metric weights. In Lighthouse 13, as in Lighthouse 10, Total Blocking Time, Largest Contentful Paint and Cumulative Layout Shift carry 80 percent of the Performance score, so main-thread JavaScript, the largest element and unsized media come first. Re-run the same median after each change.

Read the report in this order: the metrics, then the insights and diagnostics, and leave the passed audits alone. Only metrics count toward the Performance score, “not the results of Opportunities or Diagnostics”, though improving those “likely improve the metric values”. Lighthouse 13 removed the older performance audits that insights replaced, and the same insights appear in the DevTools Performance panel; Chrome’s performance insights reference lists each one.

Metric and weightWhat the report points atThe usual cause on a builder-made appWho owns the detail
Total Blocking Time, 30%Reduce JavaScript execution time; Minimize main-thread work; Avoid long main-thread tasksOne large client bundle, with chart libraries loaded on every routehow to reduce JavaScript bundle size
Largest Contentful Paint, 25%LCP breakdown; LCP request discovery; Improve image delivery; Render-blocking requestsAn unoptimized hero image, or a first screen rendered in the browser after the JavaScript arrivesan image optimization checklist for websites
Cumulative Layout Shift, 25%Layout shift culprits; Image elements do not have explicit width and heightImages and embeds without dimensions, banners that load lateFix in place: set width and height, or reserve the space
First Contentful Paint and Speed Index, 10% eachRender-blocking requests; Document request latency; Font displayRender-blocking stylesheets, synchronous third-party tags, a slow server responsethe caching strategies web applications need
Third-party code, across metricsThird partiesChat widgets, analytics and tag managers loaded at startupLoad them after the first interaction, or drop them
Very large DOM on list viewsOptimize DOM sizeA long list rendered in fullPaginate or virtualize the list

The cause column is my reading, one clause a row; the full list of builder-made failure patterns is the “Common AI-built app performance failures” section of the Core Web Vitals article linked below. After each fix, re-run the same 5-run median on the same profile and record it. Change one thing at a time, or the before and after proves nothing. For some platforms the report adds framework advice of its own: stack packs “detect what platform your site is built on and display specific stack-based recommendations”.

Test largest contentful paint on mobile

Largest Contentful Paint on mobile is tested in 5 steps: run the mobile audit, open the LCP breakdown to see which element it was and which subpart took longest, confirm it in the Performance panel with throttling on, fix that subpart, and re-run the median.

LCP carries a quarter of the Performance score, 25 percent in both Lighthouse 10 and 13, and it is the metric a founder can see: the moment the main image or headline appears.

  1. 01 Run the audit on the mobile profile and note LCP from the median run.
  2. 02 Open the LCP breakdown insight: it shows the LCP element and splits the time into Time to First Byte, resource load delay, resource load duration and element render delay.
  3. 03 Confirm it in the DevTools Performance panel: under Capture settings set Network and CPU throttling, click Record and reload, and read the same breakdown in the Insights sidebar.
  4. 04 Fix the longest subpart first; Chrome's guidance is that, ideally, most LCP time goes to loading the resource, not to the delays around it.
  5. 05 Re-run the five-run median on the mobile profile and record the new LCP next to the old one.

The good threshold for LCP, and the causes by element type, are in Core Web Vitals for AI-built apps. A real phone on a real network is the last check. The field section of PageSpeed Insights is the long-run one, since it reports the 75th percentile of real visits over the previous 28 days.

Core Web Vitals in a Lighthouse report: lab numbers and field numbers

Lighthouse and Core Web Vitals measure the same page from two sides. Lighthouse reports Largest Contentful Paint and Cumulative Layout Shift from one lab load, and Total Blocking Time where Interaction to Next Paint would be. The Core Web Vitals verdict comes from real Chrome visits, read at the 75th percentile.

Core Web VitalWhat Lighthouse shows for it in the labWhere the field number comes from
Largest Contentful Paint (loading)Measured in the lab load; 25% of the Performance scoreChrome User Experience Report data from real Chrome users, shown in PageSpeed Insights’ field section and Search Console’s Core Web Vitals report
Interaction to Next Paint (interactivity)Not measured in a page-load audit; Total Blocking Time is the lab proxy, 30% of the scoreThe same Chrome User Experience Report data
Cumulative Layout Shift (visual stability)Measured in the lab load; 25% of the scoreThe same Chrome User Experience Report data

web.dev’s Web Vitals article is plain about the split: TBT “is a proxy for INP”, and lab measurement “is not a substitute for field measurement”. Search Console’s Core Web Vitals report draws on the same Chrome User Experience Report that PageSpeed Insights shows, data it calls “real world usage data (sometimes called field data)”.

A new app with little traffic may have no field record at all: PageSpeed Insights falls back to the origin, and if the origin has too little data it shows none. That is a reason to run the lab audit carefully, never a reason to present the lab number as field data.

What moving these numbers can be worth is best read from a published case rather than a promise. web.dev’s Nuvemshop case study, published June 24, 2026, reports that the share of its stores with healthy LCP went from 57% to 96% in one year, and that for the same cohort of Brazilian stores, mobile visitors from Google organic search showed an 8.9% increase in conversion rate (session-to-paid-order) between January 2025 and January 2026. That is one platform’s result, not a forecast for yours. The thresholds, the per-metric causes, the order in which to use the tools and a verification record for the vitals themselves are in the Core Web Vitals for AI-built apps article linked above.

How to verify it

A Lighthouse review is verified by its record: one row per page with the device profile, the Lighthouse version, the numeric targets, and the before and after medians, plus a keyboard check of signup and the main task that no automated score covers.

This is the record as a template. The example row shows what goes in each cell; the measured columns stay empty until you run it.

PageDevice profileLighthouse versionTargetsBefore (median of 5: score, LCP, TBT, CLS)After (median of 5)Date
/pricing (example)Mobile: Emulated Moto G Power, Slow 4GAs printed in the report footerPerformance 90+, LCP 2,500 ms, TBT 200 ms, CLS 0.1(fill in)(fill in)(fill in)
/dashboard (example)Mobile: Emulated Moto G Power, Slow 4GAs printed in the report footerWritten from the baseline, with its reason(fill in)(fill in)(fill in)

Keep the JSON and HTML reports of every run next to the table. Pass: every row meets its written target on the mobile profile. Fail: a target met only on desktop, only on one lucky run, or only on the dev server. The result holds for the production build on the default mobile preset. If the Lighthouse version changes between the before and the after, write both versions on the row, because the weights can differ from one version to the next.

The accessibility score covers only part of the job, and the report says so in its own words: “Automatic detection can only detect a subset of issues and does not guarantee the accessibility of your web app, so manual testing is also encouraged.” Lighthouse accessibility scoring adds that the items left for a person to check do not affect the score at all. My checklist for the manual half, on the core pages:

  1. 01 Tab through signup and the main task with the keyboard only, and finish both.
  2. 02 Every focused control shows a visible focus indicator.
  3. 03 A modal closes with Escape and sends focus back to the control that opened it.
  4. 04 Every form field announces its label, and every error is announced with it.
  5. 05 Nothing important is conveyed by color alone.

Keep a short dated note for each check alongside the reports. The full keyboard walk and the accessibility baseline belong to the accessibility audit linked in the targets section. Lighthouse loads one page for one visitor; the server under many visitors is the job of API load testing, and growth past one machine is the subject of scaling web applications.

Deliverable 9.5 of the Production Hardening Sprint is verified the same way: “Report the chosen pages, device profile, numerical targets, and final results; manually check key accessibility interactions.”

Where the sprint does this

In the sprint, deliverable 9.5, Lighthouse performance review, is where we run Lighthouse on representative pages, implement performance and accessibility improvements, and deliver a passing result against recorded acceptance targets. It sits in area 09, Performance, which holds 7 of the 123 deliverables in the published scope, area 9. The result for every scope item, the work completed and its verification evidence go into the production readiness report, deliverable 13.1. Building new product features or modules, completing unfinished core features or business workflows, and rebuilding core functionality that does not yet perform its intended job sit outside the sprint.

Common questions about Lighthouse scores

How do I interpret Lighthouse results?

Start with the five metric values, move on to the insights and diagnostics that explain them, and ignore what already passed. Only the metrics count toward the Performance score; the insights and diagnostics point at causes that move those metrics. Compare medians of repeated runs on the same profile, never two single runs.

What is a good Lighthouse score?

A score of 90 to 100 is Good in Chrome’s color bands, 50 to 89 needs improvement and 0 to 49 is poor. Chrome’s scoring page also says a perfect 100 is not expected, so the score that matters is the target you wrote down before the work.

How is the Lighthouse Performance Score calculated?

It is a weighted average of five metric scores. Each raw metric value is mapped to a score from 0 to 100 on a log-normal curve built from HTTP Archive data, then weighted: Total Blocking Time 30%, Largest Contentful Paint 25%, Cumulative Layout Shift 25%, First Contentful Paint 10% and Speed Index 10% in Lighthouse 13, the same weights as Lighthouse 10.

How to calculate accessibility score?

Lighthouse calculates it as a weighted average of pass or fail audits, with weights of 10, 7, 3 or 1 based on axe’s user impact assessments. An audit with even one failing element scores 0 for the page, and the items left for a person to check and the low-impact best-practice audits do not count, so 100 means no scored automated audit failed, not that the page is accessible.

Is Google Lighthouse free to use?

Yes. Lighthouse is open source under the Apache 2.0 license, it is built into Chrome DevTools with nothing to download, the command-line version installs from npm, and PageSpeed Insights runs it from a web page with no installation.