Skip to main content
All articles
Performance··3 min read

Core Web Vitals in 2025: what actually moves the needle

Google's metrics evolved. We audited 40 sites and found the same culprits: third-party scripts, unoptimized images, and layout instability from injected content.

MC
Marcus Chen
Principal Engineer

We audited forty production websites in Q1 2025. The goal was simple: identify what actually impacts Core Web Vitals versus what developers obsess over unnecessarily.

The data

MetricSites FailingPrimary Cause
LCP28/40Unoptimized images
CLS19/40Injected third-party content
INP31/40Long JavaScript tasks
TTFB12/40Slow origin response

LCP: it is almost always images

Twenty-eight sites failed LCP. Twenty-six of them had hero images served without optimization.

What works:

  • AVIF format: 30-50% smaller than WebP at equivalent quality
  • fetchpriority="high": On the LCP image only
  • Preload hints: For above-fold images
  • Proper sizing: No oversized images scaled down with CSS
  • CDN with HTTP/3: Reduces time-to-first-byte for the image itself

What does not help much:

  • Lazy loading above-fold images (actively hurts)
  • Over-engineered loading spinners
  • Complex placeholder generation

CLS: the third-party script problem

Nineteen sites had layout shift issues. In fifteen cases, the culprit was third-party scripts injecting banners, chat widgets, or ads after initial render.

Our fix: reserved space for all known injected elements.

.cookie-banner { min-height: 60px; }
.chat-widget { aspect-ratio: 1 / 1; width: 60px; }

If the script loads, it fills the reserved space. If it fails, the layout does not shift.

INP: the JavaScript tax

Thirty-one sites failed Interaction to Next Paint. The common thread: main-thread saturation from analytics, A/B testing frameworks, and client-side hydration.

Specific fixes that worked:

  1. Defer non-critical analytics: Send beacon requests after requestIdleCallback
  2. Split A/B test logic: Run assignment server-side, not client-side
  3. Hydration boundaries: Use React Server Components for static content
  4. Web Workers: Move heavy computation off the main thread
  5. Event delegation: Reduce individual event listener overhead

One client reduced INP from 380ms to 72ms simply by moving their A/B testing framework from client-side to an edge worker.

TTFB: the forgotten metric

Only twelve sites had poor TTFB, but when it is bad, everything downstream suffers.

The fix is usually geographic: move compute closer to users. Edge functions, regional databases, and CDN caching at the PoP level.

Our audit checklist

Before any client launch, we run:

  1. Lighthouse CI in CI/CD with 90+ thresholds
  2. WebPageTest from 3 continents on 4G
  3. Chrome UX Report comparison for origin-level data
  4. Real-user monitoring with 75th percentile targets
  5. Third-party script inventory with performance budgets

The bottom line

Most performance issues are not exotic. They are images, scripts, and layout shifts. Fix the basics before chasing micro-optimizations.

Core Web VitalsLCPCLSINPPerformance