14+ years building on WordPress / Replies in under 5 hours
Performance 9 min read · Updated July 2026

Optimizing WordPress for Core Web Vitals: LCP, INP and CLS

Photo of Ajay Khandal
Ajay Khandal
WordPress Developer
Optimizing WordPress for Core Web Vitals: A Developer’s Guide
TL;DR

Core Web Vitals are Google's three user experience metrics that feed into search rankings. As of March 2024, the active metrics are: LCP (Largest Contentful Paint, ≤2.5s good), INP (Interaction to Next Paint, ≤200ms good — this replaced FID on March 12, 2024), and CLS (Cumulative Layout Shift, ≤0.1 good). LCP fixes: preload the hero image with `<link rel="preload" fetchpriority="high">`, never lazy-load the LCP element, use WebP and correct image sizing, and improve TTFB through server-level caching (managed hosting + Cloudflare CDN). INP fixes: defer non-critical JavaScript (WP Rocket 'Delay JS Execution', LiteSpeed Cache), remove unused plugins, use a lightweight theme (Astra, GeneratePress) — INP is almost always a JavaScript main-thread problem. CLS fixes: ensure all `<img>` elements have explicit `width` and `height` attributes, use `font-display: swap` on web fonts, reserve space for ads/embeds with `min-height` or `aspect-ratio`. Check your real scores in Google Search Console (Core Web Vitals report uses CrUX field data, which is what Google's algorithm actually uses — not PageSpeed Insights lab data).

Core Web Vitals are Google’s standardised set of user experience metrics that feed directly into page ranking signals. Getting them right matters both 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) was retired as a Core Web Vital on March 12, 2024 and replaced by Interaction to Next Paint (INP). Any guide still referencing FID as a current metric is out of date. The three active Core Web Vitals as of 2026 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 — focus on the field data, since that’s what Google’s ranking algorithm uses. Google Search Console’s Core Web Vitals report (under Experience) gives a broader view across all your pages.

The three Core Web Vitals: thresholds and what they measure

  • Largest Contentful Paint (LCP) — time until the largest content element in the viewport (typically a hero image or H1 text) finishes loading. Good: ≤2.5s. Needs improvement: 2.5–4s. Poor: >4s.
  • Interaction to Next Paint (INP) — the 98th percentile response time across all user interactions (clicks, taps, key presses) during a page visit. Replaced FID on March 12, 2024. Good: ≤200ms. Needs improvement: 200–500ms. Poor: >500ms.
  • Cumulative Layout Shift (CLS) — total amount of unexpected layout movement during the page’s life. Good: ≤0.1. Needs improvement: 0.1–0.25. Poor: >0.25.

All three need to be in the “Good” range for a URL to pass the Core Web Vitals assessment in Google Search Console. One failing metric fails the whole URL.

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 → Performance tab → record a page load → look for the “LCP” marker in the timeline. Or use the Web Vitals Chrome extension, which highlights the LCP element directly on the page. Once you know exactly which element is causing your LCP, you know what to fix.

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 encounters 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="' . get_template_directory_uri() . '/images/hero.webp"
            fetchpriority="high">';
    }
}
add_action('wp_head', 'preload_lcp_image', 1);

Also ensure the LCP <img> element itself has fetchpriority="high" and does not have loading="lazy" — lazy loading the LCP image is a common mistake that significantly delays it.

Serve images in WebP and use correct sizing

WordPress generates WebP versions of uploaded images and outputs srcset automatically since version 5.8. Ensure your theme’s add_theme_support('post-thumbnails') and registered image sizes match the display sizes you actually use — serving a 2000px image in a 400px container wastes bandwidth and delays LCP.

For additional image compression before upload, Smush and ShortPixel both work well. The mobile-first design guide covers fetchpriority, lazy loading configuration, and responsive image setup in more detail.

Reduce Time to First Byte (TTFB)

LCP can’t start until the HTML arrives. A slow TTFB (>600ms) sets a ceiling on your LCP score regardless of image optimisation. Causes: slow hosting, no server-level caching, unoptimised database queries from too many plugins. Fixes in order of impact:

  • Use managed WordPress hosting with server-level caching (Kinsta uses LiteSpeed, WP Engine uses EverCache) — these cache full pages at the server layer, bypassing PHP entirely on cached requests
  • Add a CDN — Cloudflare’s free tier is the most practical option for most WordPress sites, reducing latency for global visitors without cost
  • Deactivate unused plugins — every active plugin adds PHP execution overhead to uncached requests

The high-performance WordPress guide covers server configuration, caching layers, and database optimisation in detail. If your goal is a perfect Lighthouse score, see the WordPress 100/100 Lighthouse score guide.

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. For caching plugin comparisons, see WP Rocket vs W3 Total Cache vs LiteSpeed Cache.

Interaction to Next Paint (INP)

INP replaced FID on March 12, 2024. The key difference: FID only measured the delay before the browser began handling the first user interaction. INP measures the actual response time of all interactions throughout a page visit — clicks, taps, keyboard input — and reports the 98th percentile (the worst interaction, discarding only the worst 2%).

A poor INP score means your page feels sluggish to interact with. The most common causes on WordPress sites:

Long JavaScript tasks blocking the main thread

JavaScript runs on the browser’s main thread. Any task longer than 50ms can delay INP. Common offenders: heavy page builder scripts (Elementor, Divi), large third-party widgets, analytics scripts that run on interaction, and unoptimised slider or animation plugins.

Fix approaches:

  • Defer non-critical JS: WP Rocket’s “Delay JavaScript Execution” feature delays third-party scripts until user interaction. LiteSpeed Cache has an equivalent setting.
  • Remove unused plugins: Every active plugin that enqueues a JavaScript file adds to the main thread load. Deactivate any plugin whose functionality you’re not actively using.
  • Use a lightweight theme: Themes like Astra and GeneratePress ship minimal JavaScript. Heavy multipurpose themes (large Themeforest themes, Divi’s builder layer) are a common root cause of poor INP scores.

Third-party scripts

Google Analytics 4, Meta Pixel, chat widgets, and ad scripts all run JavaScript that competes for the main thread. Strategies:

  • Load analytics scripts with type="module" or defer them until after interaction
  • Use a tag manager (Google Tag Manager) to load third-party tags asynchronously
  • Remove any third-party script you’re not actively using — verify against your actual analytics integrations

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 contribute 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. WordPress has generated width and height attributes on images automatically since version 5.5 — but only for images inserted through the media library. Images hardcoded into theme templates or older page builder content may still be missing these attributes. Check and add them.

Web fonts

When a web font loads after text has already rendered using a fallback font, the text reflows — this is a CLS source. Two fixes:

  • Add font-display: swap to your @font-face declarations (shows fallback text immediately, swaps when the web font loads)
  • Preload critical fonts: <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin> in <head>

Self-hosting fonts is more reliable than Google Fonts for CLS — you control the response time. The font-display: optional value is even more CLS-safe (no swap at all if the font isn’t ready within the render window) but shows the fallback more often on slow connections.

Reserve space for dynamically loaded content

  • Ads and banners: Reserve their container with a fixed min-height so the surrounding content doesn’t jump when the ad loads
  • Cookie consent banners: These are a significant CLS source — if they push content down, fix them with a fixed-position overlay style that doesn’t affect document flow
  • Embeds: YouTube videos, tweets, and other iframes need an aspect-ratio container. CSS aspect-ratio: 16/9 on the container reserves the correct space without requiring hardcoded pixel heights

Tools to measure Core Web Vitals

  • Google Search Console → Core Web Vitals report: Shows field data (real user data from CrUX) across all your pages, grouped by status. This is the authoritative source — it’s what Google’s algorithm uses.
  • PageSpeed Insights: Shows both lab data (Lighthouse, synthetic) and field data (CrUX, real users) for a specific URL. Run it on your homepage and on a typical blog post — they often have very different scores.
  • Chrome DevTools → Performance panel: Records a page load and shows exactly where time is spent, which tasks block the main thread, and when LCP fires. Necessary for diagnosing INP root causes.
  • Web Vitals Chrome extension: Shows live LCP, INP, and CLS values as you interact with a page. Highlights the LCP element in red. Fast for spot-checking.
  • GTmetrix: Lab data only (not real user data). Useful for waterfall analysis of which resources are slow, but GTmetrix scores don’t map directly to Google’s field data assessments.

WordPress-specific fix priority order

Applied in this order, these cover the vast majority of Core Web Vitals issues on WordPress sites:

  1. Hosting tier — managed WordPress hosting with server-level caching eliminates TTFB as a bottleneck. No optimisation plugin compensates for slow shared hosting.
  2. Caching plugin — WP Rocket, LiteSpeed Cache (if your host runs LiteSpeed), or W3 Total Cache. Handles page caching, CSS/JS minification, and JavaScript deferral in one plugin.
  3. LCP image optimisation — preload hint, fetchpriority="high", no loading="lazy", correct display size.
  4. WebP images — compress and convert uploaded images. WordPress handles WebP generation and srcset output automatically since 5.8.
  5. JavaScript deferral — defer or delay non-critical JS (page builder scripts, third-party widgets, analytics) to improve INP.
  6. Unused plugin removal — every inactive but installed plugin adds autoloaded option data; every active plugin adds PHP execution. Deactivate and delete anything you’re not using.
  7. Lightweight theme — if your theme is the INP bottleneck, switching to Astra or GeneratePress is faster than optimising around a heavy builder.
  8. Image dimensions and font handling — add explicit width/height to all images; use font-display: swap and preload critical fonts.

Hosting, theme, and plugin decisions made before you build the site are the biggest long-term Core Web Vitals factors — see the pre-build WordPress decisions checklist for what to get right early. For the full ranking-signal picture around performance and SEO setup, see the WordPress SEO plugins guide.

Frequently asked questions

Core Web Vitals are Google's three standardised page experience metrics: Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS). LCP measures how fast the main content loads (good: ≤2.5s). INP measures how quickly the page responds to user interactions like clicks and taps (good: ≤200ms). CLS measures how much the visible page content shifts unexpectedly during load (good: ≤0.1). All three feed into Google's page experience ranking signals. First Input Delay (FID) was retired and replaced by INP on March 12, 2024.

INP (Interaction to Next Paint) replaced FID (First Input Delay) as a Core Web Vital on March 12, 2024. FID only measured the browser's delay before beginning to handle the very first user interaction on a page. INP measures the actual response time of all interactions throughout a page session (clicks, taps, key presses) and reports the 98th percentile — giving a much more comprehensive picture of how interactive the page feels in real use. The threshold for a good INP score is ≤200ms. Any guide that still references FID as a current Core Web Vital metric is outdated.

The highest-impact LCP fixes for WordPress sites: (1) Preload the LCP image with a `` tag in `` — this tells the browser to fetch the hero image before it parses the HTML that contains the `` tag. (2) Remove `loading="lazy"` from the LCP element — lazy loading your LCP image significantly delays it. (3) Use WebP format and serve the correct display size — WordPress generates WebP versions automatically since version 5.8. (4) Reduce TTFB with server-level caching (managed WordPress hosting like Kinsta or WP Engine) and a CDN like Cloudflare.

The most common CLS causes and fixes for WordPress: (1) Missing image dimensions — add explicit `width` and `height` attributes to all `` elements so the browser reserves space before the image loads. WordPress does this automatically for media library images since version 5.5. (2) Web font FOUT/FOUT — add `font-display: swap` to your `@font-face` declarations and preload critical fonts with ``. (3) Content injected above existing content — cookie banners, ad slots, and pop-ups that push page content down. Fix with fixed-position overlays or reserved container heights. (4) Embeds without reserved space — wrap YouTube videos and other iframes in a container with `aspect-ratio: 16/9`.

Poor INP on WordPress is almost always caused by JavaScript blocking the browser's main thread. Fixes: (1) Defer non-critical JavaScript — WP Rocket's 'Delay JavaScript Execution' feature and LiteSpeed Cache's equivalent delay third-party scripts until after first user interaction. (2) Remove unused plugins — every active plugin adds PHP execution overhead and potentially JavaScript that runs on every page. (3) Use a lightweight theme — heavy multipurpose themes and page builder layers (Divi, some Elementor configurations) are a common INP root cause. (4) Audit third-party scripts — Google Analytics 4, Meta Pixel, and chat widgets all run JavaScript that competes for the main thread during interactions.

Yes, but not as a primary ranking factor. Google's page experience signals (which include Core Web Vitals) are a tiebreaker between pages with otherwise similar relevance signals — they won't compensate for poor content or weak backlinks, but they can be a differentiator between comparable pages. More practically: the Core Web Vitals thresholds Google uses for rankings are based on real user data (CrUX field data), not PageSpeed Insights lab scores. A high PageSpeed Insights lab score on a fast test connection doesn't guarantee your real users are having a good experience. Check your Core Web Vitals status in Google Search Console (Experience → Core Web Vitals), which shows how your actual visitors experience your pages.

Photo of Ajay Khandal

Written by Ajay Khandal

I'm a freelance WordPress developer with 14+ years of experience building, fixing, and speeding up sites for businesses, agencies, and store owners across the US, UK, Europe, and Australia. I specialize in custom themes, WooCommerce, and performance — the kind of work that shows up as faster load times and fewer support tickets. No account managers, no outsourced tickets — you work directly with me, with replies typically inside 5 hours.

Work with me →