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

Core Web Vitals in 2025: what actually moves the needle

Google's metrics evolved. The same culprits keep showing up in audits: third-party scripts, unoptimized images, and layout instability from injected content.

C
CIPHRX
Engineering team

When we audit production websites, the goal is simple: identify what actually impacts Core Web Vitals versus what developers obsess over unnecessarily. The pattern is remarkably consistent.

The pattern we keep seeing

MetricCommon failurePrimary cause
LCPMost failing sitesUnoptimized hero images
CLSHalf of failing sitesInjected third-party content
INPMost failing sitesLong JavaScript tasks
TTFBA minority of sitesSlow origin response

LCP: it is almost always images

When LCP fails, the cause is almost always a hero image 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

The bulk of layout-shift problems we see come from third-party scripts injecting banners, chat widgets, or ads after initial render.

The fix: reserve space for every known injected element.

.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

INP is the metric that catches the largest share of sites we audit. The common thread is main-thread saturation from analytics, A/B testing frameworks, and over-hydrated client trees.

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

Moving an A/B testing framework from client-side to an edge worker is often enough to take INP from problematic to comfortably under threshold.

TTFB: the forgotten metric

TTFB fails less often than the other metrics, 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.

The audit checklist we use

Before any 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