Core Web Vitals are Google’s standardised set of user experience metrics, and Google says good scores align with what its core ranking systems seek to reward. Getting them right matters for SEO and for how your site actually feels to use: a slow LCP, a sluggish interaction, or a layout that jumps on load are all things users notice and abandon.
One important update before we get into fixes: First Input Delay (FID) stopped being a Core Web Vital on March 12, 2024, when Interaction to Next Paint (INP) replaced it (web.dev announcement). Any guide still treating FID as a current metric is out of date. The three active Core Web Vitals are LCP, INP and CLS.
The fastest way to see where you actually stand: open PageSpeed Insights with your URL. It shows both lab data (Lighthouse) and real-user data from Google’s CrUX dataset, and the field data is the part to focus on. Google Search Console’s Core Web Vitals report (under Experience) gives a broader view across all your pages.
What Are Core Web Vitals? Thresholds for LCP, INP and CLS
Core Web Vitals are three Google metrics for real-user experience: Largest Contentful Paint (LCP) for loading, Interaction to Next Paint (INP) for responsiveness, and Cumulative Layout Shift (CLS) for visual stability. A page passes when all three meet the “good” threshold at the 75th percentile of page loads, measured separately for mobile and desktop.
| Metric | What it measures | Good | Needs improvement | Poor |
|---|---|---|---|---|
| Largest Contentful Paint (LCP) | Time until the largest content element in the viewport has rendered | ≤ 2.5s | 2.5–4s | > 4s |
| Interaction to Next Paint (INP) | How long the page takes to show visual feedback after clicks, taps and key presses | ≤ 200ms | 200–500ms | > 500ms |
| Cumulative Layout Shift (CLS) | How much visible content moves unexpectedly | ≤ 0.1 | 0.1–0.25 | > 0.25 |
Thresholds are from Google’s Web Vitals overview and the individual LCP, INP and CLS articles on web.dev.
The 75th-percentile rule is the part most site owners miss. At least three in four page loads must meet the target, so a site that feels fast on your office laptop can still fail if more than a quarter of visitors are on older phones or patchy mobile connections. One failing metric fails the whole URL.
A few details about each metric matter for WordPress sites. The LCP element can be an <img>, a video poster, a block of text, or an element with a CSS background image loaded through url(), so a hero section built as a background image still counts. INP watches every click, tap and key press during the visit and reports the slowest one, ignoring one outlier for every 50 interactions. Scrolling and hovering are not measured. CLS is a unitless score that adds up the unexpected shifts.
How to Measure Core Web Vitals, and Why Field Data and Lab Data Disagree
Field data comes from real Chrome users through the Chrome User Experience Report (CrUX), and it is what Google uses to judge your pages. Lab data comes from one simulated test in Lighthouse or Chrome DevTools. Use field data to decide whether a page passes, and lab data to work out why it fails.
PageSpeed Insights reports CrUX field data over the previous 28-day collection period, so a fix takes weeks to show fully in your scores. Its lab test runs Lighthouse, which simulates a mid-tier mobile device on a mobile network (PageSpeed Insights documentation).
A common frustration is a high Lighthouse score while Search Console shows Core Web Vitals failures. It happens for predictable reasons:
- Real visitors use a spread of devices and connections, and the 75th percentile includes the slow ones.
- TTFB can spike under real traffic, or for logged-in and uncached visits, while the lab test hits a warm cache.
- Third-party scripts such as ads, chat widgets and consent tools may behave differently for real users than in a single test run.
- INP depends on real interactions. A page load test cannot open your menus, filters and forms the way visitors do.
So prioritise Search Console field data, then diagnose with Lighthouse and DevTools.
| Tool | Data type | Use it for |
|---|---|---|
| Google Search Console, Core Web Vitals report | Field (CrUX) | Site-wide status grouped by URL type. This is the authoritative view of how Google sees your pages. |
| PageSpeed Insights | Field and lab | One URL at a time. Run it on your homepage and on a typical blog post; they often score very differently. |
| Chrome DevTools, Performance panel | Lab, plus live local metrics | Finding the LCP element, long tasks on the main thread, and slow interactions. Since Chrome 129 it shows real-time LCP, INP and CLS, which replaced the retired Web Vitals extension. |
| GTmetrix | Lab only | Waterfall analysis of slow resources. Its scores don’t map directly to Google’s field data assessment. |
Largest Contentful Paint (LCP)
LCP is the one that matters most on most WordPress sites. The LCP element is almost always the hero image on the homepage or a post’s featured image at the top of the page. Every millisecond saved on that specific resource directly improves your LCP score.
Identify your LCP element
Open Chrome DevTools, go to the Performance tab, record a page load, and look for the LCP marker in the timeline. The live metrics view in the same panel also names the LCP element as you load the page. Once you know exactly which element is causing your LCP, you know what to fix.
Reduce Time to First Byte (TTFB)
LCP can’t start until the HTML arrives, so a slow server response sets a floor under your LCP score regardless of image optimisation. TTFB sits outside the Core Web Vitals set, and web.dev suggests most sites should aim for a TTFB of 0.8 seconds or less. Causes: slow hosting, no page caching, and slow database queries from too many plugins. Fixes in order of impact:
- Use hosting with server-level page caching, which serves cached pages without running PHP or MySQL at all. For uncached requests (new pages, logged-in users, carts), faster hosting is the only fix.
- Add a full-page caching plugin if your host doesn’t cache at the server. WP Rocket and LiteSpeed Cache are the two main options; the WP Rocket vs W3 Total Cache vs LiteSpeed Cache comparison covers which suits your host.
- Add a CDN. Cloudflare’s free tier serves static assets from edge locations close to your visitors, which lowers latency for visitors far from your server.
- Deactivate unused plugins, since every active plugin adds PHP execution to uncached requests.
The high-performance WordPress guide covers server configuration, caching layers and database optimisation in detail.
Preload the LCP image
The single highest-impact LCP fix for most WordPress sites: add a preload hint for the LCP image so the browser fetches it before it reaches the <img> tag in the HTML. Add to your theme’s functions.php:
function preload_lcp_image() {
if ( is_front_page() ) {
echo '<link rel="preload" as="image" href="' . esc_url( get_template_directory_uri() . '/images/hero.webp' ) . '" fetchpriority="high">' . "\n";
}
}
add_action( 'wp_head', 'preload_lcp_image', 1 );
Also give the LCP <img> element itself fetchpriority="high", and make sure it does not carry loading="lazy". WordPress has lazy-loaded images by default since version 5.5, which is right for images below the fold and wrong for the hero. Since WordPress 6.3, core adds fetchpriority="high" to the image it judges most likely to be the LCP image. Images output by sliders, page builders or custom theme code don’t always go through that logic, so check the rendered HTML of your hero. Most caching plugins also have an LCP preload setting.
Serve images in WebP and use correct sizing
WordPress has accepted WebP uploads since version 5.8 and outputs srcset so browsers can pick a suitable size. It doesn’t convert your existing JPEGs on its own: ShortPixel, Imagify and Smush can bulk-convert the media library and serve WebP to supporting browsers. Make sure your registered image sizes match the display sizes you actually use, because serving a 2000px image in a 400px container wastes bandwidth and delays LCP.
The mobile-first design guide covers fetchpriority, lazy loading configuration and responsive image setup in more detail.
Minify and defer render-blocking resources
CSS that blocks rendering delays LCP. JavaScript that blocks the main thread delays both LCP and INP. WP Rocket, LiteSpeed Cache and Autoptimize all handle CSS/JS minification and deferral. The most important setting: defer or delay non-critical JavaScript so it doesn’t block the LCP render.
Interaction to Next Paint (INP)
INP replaced FID on March 12, 2024. FID only measured the delay before the browser began handling the first interaction. INP observes the latency of all click, tap and keyboard interactions throughout the visit, up to the next frame the browser paints, and reports the longest one, ignoring outliers. A page could pass FID easily and still fail INP if later interactions (opening a dropdown, clicking a tab, submitting a form) are slow.
For WordPress sites, INP failures almost always come down to JavaScript on the main thread, and WordPress sites pick up JavaScript from every plugin installed. That makes INP the hardest of the three to fix.
Find the long tasks
JavaScript runs on the browser’s main thread, and web.dev defines any task over 50 milliseconds as a long task. In the DevTools Performance panel, record yourself using the page (open the menu, use a filter, submit a form) and look for long tasks marked in red. The call tree under each one shows which script file caused it. Common offenders: page builder scripts, sliders and animation plugins, large third-party widgets, and analytics code that runs on interaction.
Defer, delay and remove JavaScript
- Delay non-critical scripts. WP Rocket’s “Delay JavaScript Execution” feature holds third-party scripts until the first user interaction, and LiteSpeed Cache has an equivalent setting.
- Remove plugins you don’t use. Every active plugin that enqueues a JavaScript file adds to the main thread’s work.
- Unload scripts from pages that don’t need them. A contact form plugin loading its assets on every page is a classic case: the script runs on product pages where no form exists. Perfmatters and Asset CleanUp Pro let you disable specific plugin scripts by URL. To fix it properly in theme code, see the guide to properly enqueuing scripts and styles in WordPress.
Page builders and heavy themes
Page builders (Elementor, Divi, WPBakery) load substantial front-end JavaScript to power their interactive and responsive features, and heavy multipurpose themes do the same. Lightweight themes such as Astra and GeneratePress, a block theme, or a custom theme carry a fraction of that footprint. If the theme or builder is the INP bottleneck, switching is often faster than optimising around it. The page builders vs custom code comparison covers the performance trade-offs.
Third-party scripts
Google Analytics 4, Meta Pixel, chat widgets and ad scripts all run JavaScript that competes for the main thread. What helps:
- Load them with
asyncordefer, or delay them until after the first interaction. - Use Google Tag Manager so tags load asynchronously from one container.
- Remove any third-party script you no longer use. Check it against your actual analytics and marketing integrations first.
WooCommerce cart fragments
The cart fragments script keeps the mini cart count up to date with an AJAX request to the server. Before WooCommerce 7.8 it was enqueued on every page; since 7.8 it only loads where the Cart Widget is rendered. If your theme still shows a live cart widget in the header on every page, that request runs on every page too, adding main-thread work and server load. The WooCommerce performance guide covers this and the other store-specific bottlenecks.
Cumulative Layout Shift (CLS)
CLS measures how much the visible page content moves unexpectedly after initial render. A banner sliding in above the nav, an image loading without reserved space, or a font swap that reflows text all add to CLS.
Set explicit image dimensions
The most common CLS cause: images without width and height attributes. Without them, the browser can’t reserve space before the image loads, so surrounding content jumps when the image appears. Since WordPress 5.5, core back-fills width and height on images in post content. Images hardcoded into theme templates, custom fields or older page builder content may still be missing them, so check and add them.
Web fonts
When a web font loads after text has already rendered in a fallback font, the text reflows, and that shift counts towards CLS. Fonts loaded from fonts.googleapis.com arrive in two steps (the CSS file, then the font files), which widens that window. Fixes in order of effectiveness:
- Self-host your fonts. You control the response time, and visitor IP addresses are no longer sent to Google’s servers, which some EU sites prefer for GDPR reasons.
- Preload the critical font file:
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>in<head>. - Add
font-display: swapto your@font-facedeclarations. It shows fallback text immediately and swaps when the web font loads, so the shift gets smaller without disappearing.
The font-display: optional value is even safer for CLS (no swap at all if the font isn’t ready within the render window), at the cost of showing the fallback more often on slow connections.
Reserve space for dynamically loaded content
- Give ad and banner containers a fixed
min-heightso the surrounding content doesn’t jump when the ad loads. - Show cookie consent banners as a fixed-position overlay or sticky footer. A banner that pushes page content down when it appears is a layout shift.
- Wrap YouTube videos, social embeds and other iframes in a container with CSS
aspect-ratio: 16/9, which reserves the right space without hardcoded pixel heights.
What Can You Realistically Expect From Core Web Vitals Work?
Most WordPress sites can reach good LCP and CLS with page caching, image optimisation and correct image dimensions. INP usually needs more investigation, because you have to find which JavaScript loads on each page and remove what isn’t needed there. Field data then takes up to 28 days to reflect the fixes.
A perfect Lighthouse score (100/100) doesn’t guarantee good Core Web Vitals in Search Console. Lab data is controlled and repeatable; field data reflects your visitors’ actual devices, connections and interaction patterns. If the goal is a perfect lab score as well, the WordPress 100/100 Lighthouse score guide covers HTTP headers, resource hints, server configuration and the full script audit. For an example of this work on a real site, see the news site Core Web Vitals case study.
WordPress Core Web Vitals Checklist: The Fix Order I Follow
I work through Core Web Vitals fixes in this order because the early steps remove the biggest bottlenecks and make the later ones easier to measure. Hosting and caching come first, then the LCP image, then JavaScript, then layout stability. Applied in sequence, these cover the vast majority of WordPress Core Web Vitals issues I see.
- Check the hosting tier. Server-level page caching takes TTFB out of the picture, and no optimisation plugin compensates for slow shared hosting.
- Set up a caching plugin: WP Rocket, LiteSpeed Cache (if your host runs LiteSpeed) or W3 Total Cache. It handles page caching, CSS/JS minification and JavaScript deferral in one place.
- Optimise the LCP image: preload hint,
fetchpriority="high", noloading="lazy", and the correct display size. - Convert images to WebP. WordPress has accepted WebP uploads since 5.8; use a plugin to convert the existing library.
- Defer or delay non-critical JavaScript (page builder scripts, third-party widgets, analytics) to improve INP.
- Remove unused plugins, and unload plugin scripts from pages that don’t use them.
- Switch to a lightweight theme if the theme or page builder is the INP bottleneck. Astra, GeneratePress or a custom theme is often faster than optimising around a heavy builder.
- Fix image dimensions and font loading: explicit
width/heighton all images, self-hosted fonts, a preload for the critical font, andfont-display: swap.
Hosting, theme and plugin decisions made before you build the site are the biggest long-term Core Web Vitals factors. The pre-build WordPress decisions checklist covers what to get right early, and the WordPress SEO plugins guide covers the wider SEO setup. If your field data is failing and you want a prioritised fix list, my WordPress speed optimization service covers it. Most audits can start with read-only access to your Search Console and PageSpeed data.


