Core Web Vitals are Google’s page experience metrics. They affect rankings, and they affect every reader who lands on your site. A blog with poor vitals loads slow, feels janky, and bleeds visitors. This post is the practical troubleshooting guide.

Short answer: Three metrics matter — LCP (largest contentful paint, under 2.5s), INP (interaction to next paint, under 200ms), and CLS (cumulative layout shift, under 0.1). Fix LCP by optimizing the hero image and reducing render-blocking scripts. Fix INP by reducing JavaScript. Fix CLS by reserving space for images, ads, and embeds.
A Core Web Vitals report showing LCP, INP, and CLS metrics in green, orange, and red bands

What Core Web Vitals are

Google measures three real-world performance metrics from actual Chrome users:

  • LCP (Largest Contentful Paint): how long until the biggest visible element loads. Target: under 2.5 seconds.
  • INP (Interaction to Next Paint): how responsive the page is to clicks/taps. Replaced FID in 2024. Target: under 200ms.
  • CLS (Cumulative Layout Shift): how much the page jumps around as it loads. Target: under 0.1.

Each metric has three bands: Good (green), Needs Improvement (orange), Poor (red).

Where to measure

PageSpeed Insights

pagespeed.web.dev. Enter your URL. Shows both lab data (synthetic test) and field data (real Chrome users’ experience — if available).

The field data is what Google uses for rankings. Lab data helps you debug.

Google Search Console

Search Console → Core Web Vitals. Shows site-wide field data grouped by URL pattern.

This is where you find which page groups have poor vitals.

Chrome DevTools Performance tab

For deep debugging — see exactly what’s blocking and when.

Fixing LCP

LCP is usually the hero image, the post title, or the first paragraph.

The hero image is the biggest LCP killer

Common causes:

  • Image too large (unoptimized JPEG/PNG, multiple MB).
  • Wrong format (PNG when WebP would work).
  • Image lazy-loaded when it shouldn’t be (above-the-fold images should NOT be lazy).
  • Image dimensions not set.
  • Image served from slow source (Squarespace CDN after migration, hot-linked image).

Fixes

  • Convert featured images to WebP. Plugins: Imagify, ShortPixel, Smush.
  • Resize. Featured images don’t need to be 4000px wide. 1800px is plenty.
  • Set fetchpriority="high" on the hero image. Most modern themes/SEO plugins do this; verify.
  • Exclude above-the-fold images from lazy loading.
  • Preload critical font files.
  • Self-host fonts instead of Google Fonts CDN (one less DNS lookup).

Render-blocking scripts

JavaScript and CSS that loads in <head> blocks rendering. Cuts into LCP.

Fix:

  • Move non-essential JS to footer.
  • Add defer or async to script tags.
  • Caching plugins (WP Rocket, FlyingPress) do this automatically.
  • Remove unused plugins — every plugin adds scripts.

Fixing INP

INP measures how quickly the page responds to user interactions.

Main causes

  • Heavy JavaScript on the page.
  • Third-party scripts (ads, analytics, embed widgets).
  • Inefficient event handlers.
  • Big DOM (too many elements).

Fixes

  • Reduce JavaScript volume. Audit plugins — each adds scripts.
  • Lazy-load third-party embeds (YouTube via lite-youtube-embed, social embeds via plugins that defer).
  • Delay non-critical JavaScript until user interaction (WP Rocket has “Delay JavaScript Execution” feature).
  • Use a code splitting / modern asset pipeline if you’re customizing themes.

Ads and INP

Ad scripts are the biggest INP killer on monetized blogs.

  • Lazy-load ad slots (don’t load ads until user scrolls near them).
  • Reduce ad density.
  • Mediavine and Raptive optimize this internally; AdSense Auto Ads less so.

Fixing CLS

CLS is “things moving around as the page loads.” Frustrating to users. Easy to fix.

Common causes

  • Images without width/height attributes (browser doesn’t know how much space to reserve).
  • Ads loading in and pushing content down.
  • Embeds (tweets, Instagram) loading and resizing.
  • Web fonts loading and reflowing text.
  • Dynamically injected content (cookie banners, popups).

Fixes

  • Set width and height on every <img>. Modern WordPress does this automatically.
  • Reserve fixed space for ad slots (set min-height on ad containers).
  • Reserve space for embeds (CSS aspect-ratio property, or fixed dimensions).
  • Use font-display: optional or swap with size-adjust to minimize font reflow.
  • Don’t inject elements above existing content (banners at the top push everything down — CLS spike).
A waterfall chart showing render-blocking resources and how to optimize them

WordPress-specific optimization steps

1. Caching

Essential. Reduces TTFB (time to first byte) which feeds into LCP.

  • WP Rocket (paid, simplest).
  • LiteSpeed Cache (free, if host supports LiteSpeed).
  • W3 Total Cache (free, complex).
  • WP Super Cache (free, simple).

2. Image optimization

  • Convert to WebP.
  • Resize uploads.
  • Use a CDN with image optimization (Cloudflare with Polish, Bunny.net optimizer).

3. Reduce plugin count

Each plugin adds JavaScript, CSS, and PHP overhead. Audit:

  • Remove plugins not used in last 30 days.
  • Replace multiple single-purpose plugins with one multi-purpose plugin where reasonable.
  • Avoid plugins that load assets sitewide for features used on one page.

4. CDN

Cloudflare free tier handles static asset CDN, basic optimization, and DDoS protection.

For better performance: Cloudflare Pro / Business, BunnyCDN.

5. Database optimization

Old WordPress sites accumulate post revisions, transients, spam comments.

  • WP-Optimize: cleans database.
  • Limit post revisions in wp-config.php.

6. Hosting

Cheap shared hosting often capped at slow PHP execution.

Upgrade to managed WordPress (SiteGround GoGeek+, WP Engine, Kinsta) for measurable Core Web Vitals improvement.

Common WordPress performance plugins

  • WP Rocket: caching, CSS/JS optimization, lazy loading, delay JS. Paid, $59+/year.
  • FlyingPress: similar feature set, often faster results. $60+/year.
  • LiteSpeed Cache: free, requires LiteSpeed host.
  • Perfmatters: targeted optimizations (disable scripts per page, lazy load embeds). $24.95+/year.
  • Autoptimize: free CSS/JS optimization.

The 80/20 priority list

If you only do five things:

  1. Convert images to WebP.
  2. Install a caching plugin and enable basic options.
  3. Set up Cloudflare in front of your site.
  4. Audit and remove unused plugins.
  5. Lazy-load YouTube embeds.

Those five usually move a poor-vitals site to passing.

Mobile vs desktop

Google primarily uses mobile data for ranking. Mobile is harder because:

  • Slower CPUs.
  • Slower networks.
  • Smaller screens (different LCP elements).

Test on mobile via PageSpeed Insights. Mobile-passing is the goal.

What “good enough” looks like

You don’t need 100/100 scores. Targets:

  • LCP under 2.5s on mobile.
  • INP under 200ms.
  • CLS under 0.1.

That’s “Good” across all three. Pursuing perfect Lighthouse scores has diminishing returns.

Monitoring over time

Set up monitoring:

  • Google Search Console Core Web Vitals report (weekly check).
  • PageSpeed Insights occasionally.
  • Real User Monitoring (RUM) via Cloudflare Web Analytics or third-party tools.

Vitals can degrade as you add plugins, third-party scripts, or larger images. Catch regressions early.

The honest summary

Core Web Vitals affect rankings and reader experience. LCP is usually your hero image or render-blocking scripts. INP is JavaScript-heavy plugins and ads. CLS is unreserved space for images, ads, embeds. WordPress fixes are well-known: WebP conversion, caching plugin, Cloudflare, plugin audit, lazy-loaded embeds. You don’t need a perfect score; you need green across all three.