← All articles

Core Web Vitals: why your site feels slow on mobile

Published July 19, 2026 · By LW Forge · 3 min read

If your Core Web Vitals are failing, the cause is rarely heavy application code. Most of the time the browser is blocked from painting anything until a handful of resources finish downloading and executing. On mobile, over a throttled connection, that wait can stretch to 8 seconds or more before the user sees a single pixel.

The good news: the culprit is almost always the same, a free tool will point straight at it, and the fixes don't require rewriting your site.

What Core Web Vitals actually measure

Google's Core Web Vitals are three field metrics, each with a "good" threshold:

  • LCP (Largest Contentful Paint): how long until the main content appears. Good is under 2.5 s.
  • INP (Interaction to Next Paint): how quickly the page responds to input. Good is under 200 ms.
  • CLS (Cumulative Layout Shift): how much the layout jumps around while loading. Good is under 0.1.

They matter twice over: they feed Google's page experience signal — measured against the mobile experience — and they track almost linearly with conversion. A page that paints late loses rankings and loses the visitors it still gets.

The usual culprit: render-blocking resources

When the browser parses your HTML <head>, it stops and waits for every synchronous <script> and every stylesheet before it paints the page. Each one is a round trip. Stack a few and you've built a wall between the user and your content — and your LCP pays for every brick.

The usual suspects:

  • A runtime CSS framework (for example, a CDN that generates styles in the browser instead of shipping a prebuilt file).
  • Web-font stylesheets loaded synchronously from a third-party origin.
  • Any <script src> in the <head> without defer or async.
  • Oversized images — they don't block first paint, but they drag the LCP element itself.

How to diagnose it

Run PageSpeed Insights against your page and read the mobile score, not desktop — that's what Google indexes against and where problems surface first.

Look at the First Contentful Paint and Largest Contentful Paint numbers, then at the "render-blocking requests" insight: it estimates, in milliseconds, exactly how much time you'd save by removing each blocker. Prefer the field data (real users) over lab data when both are available.

The fixes, from safest to boldest

  1. Ship prebuilt CSS. If your styles are generated at runtime, move that work to build time. The browser downloads one small, static file instead of a large script that has to run first.
  2. Make font stylesheets non-blocking. Load them with a print-media swap so text renders immediately in a fallback font, then upgrades when the web font arrives.
  3. Defer your scripts. Anything not needed for the first paint belongs at the end of the body, or carries defer.
  4. Convert images to WebP with a fallback — same content at a fraction of the weight.

None of these require a rewrite. They're surgical changes to the <head> and the build pipeline.

A real case: from the 50s to the 70s without a rewrite

We ran exactly this exercise on our own site. Replacing runtime-generated CSS with a prebuilt file took the mobile performance score from 56 to 73, with FCP dropping from 8.9 s to 4.4 s and LCP from 10.5 s to 4.5 s. Converting images to WebP cut 2.79 MB down to 283 KB — roughly 90% of the weight. Not a single line of content changed.

What remained (third-party font stylesheets) became the next iteration — Core Web Vitals work is incremental, not a big bang.

Performance is a product feature, not a technical footnote. If you want a second set of eyes on your Core Web Vitals — a diagnosis with a prioritized fix plan — that's what we do.

Frequently Asked Questions

Do Core Web Vitals affect Google rankings?

Yes — they feed Google's page experience signal, measured against the mobile experience, and they also track closely with conversion.

How do you diagnose why Core Web Vitals are failing?

Run PageSpeed Insights and check the mobile score, looking at FCP, LCP (good is under 2.5s), and the "render-blocking requests" insight.

What fixes improve Core Web Vitals without a rewrite?

Shipping prebuilt CSS instead of runtime-generated styles, making font stylesheets non-blocking, deferring non-essential scripts, and converting images to WebP.

PerformanceCore Web VitalsWeb