Skip to content

6 frontend mistakes that tank your Lighthouse score in 2026

Web · June 27, 2026 · 6 min read · Updated November 8, 2026

Cells of black, white and grey packed edge to edge

A Lighthouse performance score of 98 on your laptop and 41 on a real phone is not a measurement error. It is the distance between a lab test and the field, and most teams never see the second number until a client forwards a PageSpeed report. Lighthouse is a synthetic audit: it loads your page once, on a simulated mid-tier device and a throttled network, and grades the result. Google ranks on something else, the Core Web Vitals collected from real Chrome users. When the two disagree, production is the one your users feel.

These are the six mistakes we see most often when a Next.js or React app scores well in development and badly in production. Each one maps to a specific metric and a specific weight, so fixing the right one first is most of the work.

How Lighthouse actually scores performance

The performance score is a weighted average of five lab metrics. In Lighthouse 12, the current model assigns:

  • Total Blocking Time (TBT): 30%, the single heaviest metric
  • Largest Contentful Paint (LCP): 25%
  • Cumulative Layout Shift (CLS): 25%
  • First Contentful Paint (FCP): 10%
  • Speed Index: 10%

TBT and LCP together are 55% of the number. Improving a 30%-weighted metric moves the score three times more than improving a 10%-weighted one, which is why "we shaved 200ms off First Contentful Paint" often does nothing visible to the grade. One metric is missing from that list on purpose. Interaction to Next Paint (INP) replaced First Input Delay as a Core Web Vital on 12 March 2024, but INP is a field metric. It does not appear in the Lighthouse lab score at all. You can score 100 in the lab and still fail INP for every real user.

Mistake 1: Reading the lab score as if it were the field score

The green number in your terminal is a single synthetic run. Google's ranking signal, and the assessment in Search Console, come from the Chrome User Experience Report, aggregated at the 75th percentile of real visits. A page passes Core Web Vitals only when 75% of visits hit LCP under 2.5s, INP under 200ms, and CLS under 0.1. A lab score of 95 with failing field data is common, and the field is what ranks. Treat the lab score as a debugging tool that tells you where to look, not as the result. The result lives in the field data.

Mistake 2: A render-blocking head

Every synchronous <script> and every stylesheet in the document head blocks the browser from painting. Third-party tags are the usual culprit: analytics, consent banners, A/B testing tools, chat widgets, tag managers, most of which default to synchronous loading. They delay FCP and LCP, and their main-thread work inflates TBT. The fix is mechanical. Defer or async every non-critical script, load third-party tags after interaction or off the main thread, and inline only the critical CSS the first screen needs. Render-blocking requests are one of the most common reasons a page fails LCP even after the images are optimized.

Mistake 3: Lazy-loading the LCP image

The single most common LCP regression we find is loading="lazy" on the hero image. Lazy-loading is correct for everything below the fold and wrong for the one element that defines LCP, because the browser delays the request that the metric is timing. Frameworks that lazy-load by default hide this behind a component, so it is easy to ship without noticing. Mark the LCP image eager, add fetchpriority="high", and preload it. Then confirm it is actually optimized: a 2MB hero served as a PNG will fail LCP on a throttled connection no matter how you prioritize the request.

Mistake 4: Hydrating the whole page

JavaScript is the metric killer. Every kilobyte you ship is parsed, compiled, and executed on the main thread, and on a mid-tier phone that thread runs roughly four times slower than your laptop. Shipping a fully client-rendered page, or hydrating static content that never needed interactivity, drives TBT (30% of the score) straight up and degrades field INP on every tap. This is where Server Components, partial hydration, and a ruthless bundle audit pay for themselves. We covered the heavier libraries in the immersive web stack: most of them do not belong on a marketing page.

Mistake 5: Layout that shifts under the user

CLS is 25% of the score and the easiest to miss in development, because layout shifts only appear when assets load slowly. Three offenders repeat: images and video without explicit width and height (or an aspect-ratio box), web fonts that swap and reflow the text, and content injected above existing content such as banners, ads, and late embeds. Reserve space for everything that loads late. Set font-display deliberately and preload the font files. An empty container with fixed dimensions beats a layout that jumps after first paint.

Mistake 6: Testing on your own machine

Lighthouse mobile simulates a mid-tier device on a throttled connection. Your development machine is an M-series laptop on office fibre. The two can differ by 50 points or more, and the field sits closer to the throttled run. Auditing in your everyday browser, signed in, with extensions active, makes it worse: extensions inject scripts that count against the score. Test in an incognito window at minimum, or run Lighthouse in CI on a fixed device profile so the number is comparable between commits instead of between machines.

How to stop the regressions from coming back

One-off fixes decay. A page that scores 95 today drifts back into the red as features ship, scripts get added, and images grow. The durable fix is a budget enforced in CI. Run Lighthouse CI on every pull request with a performance budget, a minimum score or hard caps on TBT and LCP, and fail the build when a change crosses it. Pair that lab gate with field monitoring from the Chrome User Experience Report or your own real-user data: the lab catches regressions before release, the field tells you what users actually get. For the procedural version of shipping green from the start, see how we ship Core Web Vitals in green on Next.js.

Sources

Frequently asked questions

Rather have it done for you?

We design and build this kind of work for clients. Tell us what you need.