# WordPress Core Web Vitals: passing LCP, INP and CLS on WordPress

> Core Web Vitals on WordPress depend on four levers: hosting and page caching, the theme or page builder, plugins and their scripts, and images. What fails each metric on WordPress and the fix for each.

Updated 2026-09-26 · WordPress & WooCommerce · HTML version: https://getreport.app/guides/wordpress-core-web-vitals

WordPress sites pass or fail Core Web Vitals on four levers: how fast the server answers (hosting and page caching), how much the theme or page builder sends, what plugins add to every page, and how images are loaded. WordPress core itself helps: it lazy-loads images below the fold, marks the likely LCP image with `fetchpriority="high"` and adds image dimensions. Most failing WordPress Core Web Vitals come from what is installed on top of core, and each metric has its usual WordPress culprits.

This guide is for WordPress site owners and the people who build and maintain their sites. It goes metric by metric: what fails LCP, INP and CLS on WordPress, how to find it, and the fix. For the metrics themselves, read [Core Web Vitals explained for site owners](https://getreport.app/guides/core-web-vitals-for-site-owners); for a general speed-up checklist, see [how to speed up a WordPress site](https://getreport.app/guides/speed-up-wordpress-site).

## Quick answer

- **LCP** fails on WordPress because of a slow uncached server, a hero image or slider that is lazy-loaded or oversized, and builder CSS and scripts that block rendering.
- **INP** fails because of JavaScript: page builder widgets, sliders, pop-ups, chat, tag managers and WooCommerce add-ons all running on the main thread.
- **CLS** fails because of cookie banners and notices pushing content, ads without reserved space, web fonts swapping and builder images without dimensions.
- **One page cache,** a current PHP version and a host that answers cached pages in under 300 ms are the base for a good LCP.
- **Let core do its job:** do not let a theme, builder or plugin lazy-load the first image.
- **Measure in the field** with real-visitor data and wait 28 days after a fix.

## How to see where your WordPress site stands

> **Free tool:** [Core Web Vitals test: check LCP, INP and CLS](https://getreport.app/tools/core-web-vitals): Free Core Web Vitals test: LCP, INP and CLS from real Chrome users next to the lab values, rated against Google's thresholds, with what to fix. No sign-up.

The Core Web Vitals test shows LCP, INP and CLS from the Chrome UX Report for the page and the whole site, rated against Google's thresholds, with a Lighthouse lab run that names the LCP element and the scripts responsible. Test a post or product page and a category or archive page as well as the home page: on WordPress they often use different templates and different builder layouts.

> **Check: Real-user Largest Contentful Paint.** LCP is when the biggest element on screen finishes loading. Google's threshold for "good" is 2.5 s at the 75th percentile of real Chrome users.
>
> 1. Find the LCP element in the Speed module and make it smaller, earlier or both.

> **Check: Real-user Interaction to Next Paint.** INP is how long the page takes to visibly react to taps and clicks, measured on real Chrome users over the last 28 days. Google's threshold for "good" is 200 ms.
>
> 1. Cut long JavaScript tasks and heavy third-party scripts; see the INP finding above.

> **Check: Real-user Cumulative Layout Shift.** CLS on real visitors' devices over the last 28 days. Google's threshold for "good" is 0.1; layout jumps hit hardest on slow phones with late-loading ads and fonts.
>
> 1. Reserve space for images, embeds and ads; see the CLS finding above.

Then see what the page loads, plugin by plugin:

> **Free tool:** [WordPress theme and plugin detector](https://getreport.app/tools/wordpress-plugin-checker): Free WordPress theme and plugin detector: see the theme, page builder and plugins a site uses, what each plugin costs in kilobytes and which are abandoned.

The detector names the theme and page builder, and matches every request on the page to its plugin with its kilobytes and load time. That turns "too much JavaScript" into "the slider plugin loads 280 KB on pages without a slider".

## What WordPress core does for Core Web Vitals

Recent WordPress versions include performance features that help all three metrics without a plugin:

- **Lazy loading.** Since WordPress 5.5, images get `loading="lazy"`, and core tries to leave the first images in the content eager so the LCP image is not delayed.
- **Fetch priority.** Since 6.3, core adds `fetchpriority="high"` to the image it expects to be the LCP element.
- **Dimensions.** Core adds `width` and `height` to images in post content, which prevents layout shifts.
- **Modern formats.** WebP uploads work since 5.8 and AVIF since 6.5.
- **Speculative loading.** Since 6.8, WordPress prefetches a page when a visitor starts clicking a link to it, which makes the next page's LCP faster.
- **Block themes and block CSS.** Block themes load the CSS of core blocks only for the blocks on the page.

The WordPress Performance Team's **Performance Lab** plugin adds feature plugins that are not in core yet, such as Image Prioritizer and Embed Optimizer. They are optional; a site with a working page cache and sensible images can pass without them.

The catch is that themes, page builders and optimisation plugins can override core. A slider that lazy-loads its first slide, or a plugin that adds `loading="lazy"` to every image, undoes the LCP work. The lab result shows which element is the LCP and whether it is lazy-loaded.

## LCP on WordPress

LCP is the metric WordPress sites fail most. Work through the four parts of it:

**1. The server's first byte.** An uncached WordPress page runs PHP and dozens of database queries for every visitor; on shared hosting that can take over a second, and LCP can never be faster than it. The fix is exactly one page cache (the host's own, LiteSpeed Cache on LiteSpeed servers, or one caching plugin), a current PHP version and, if the server is still slow, the steps in [slow server response time on WordPress](https://getreport.app/guides/wordpress-slow-server-response-time). Two caching plugins at once are a common cause of a cache that does not work.

> **Check: Time to First Byte.** TTFB is how long the server takes to start answering. Everything else waits for it, so a slow first byte makes every other metric worse. Google's 800 ms target is for real visitors, network included; Lighthouse flags the server's own share above 600 ms (see server response time).
>
> 1. Add page caching (WordPress: WP Rocket, LiteSpeed Cache, or your host's cache; Shopify does this for you).
> 2. Put a CDN in front (Cloudflare, Bunny) so the first byte comes from a nearby edge.
> 3. Check database-heavy plugins and slow hosting; a plan with more CPU often fixes this outright.

> **Check: One caching layer is active.** Two caching or optimisation plugins fight over the same files: double minification breaks scripts, and stale pages are served from whichever cache wins.
>
> 1. Keep one caching plugin (the one your host recommends) and deactivate the other.
> 2. If the host provides server-side caching, use only its plugin and a separate image optimiser if needed.

**2. The hero image.** On most WordPress home and landing pages the LCP element is a hero image, a slider's first slide or a builder section background. Common problems:

- Uploaded at camera size, several megabytes. Resize to about 2,000–2,500 px for full width and serve WebP or AVIF.
- Lazy-loaded by the slider, the builder or an optimisation plugin. Exclude the first image from lazy loading; most caching plugins have an "exclude from lazy load" field or a setting for the first images.
- Set as a CSS background in the builder. The browser finds it only after the CSS has loaded. Use an image element where the builder allows it, or preload the image.

> **Check: Offscreen images are lazy-loaded.** Images far below the fold compete for bandwidth with the ones visitors see first. Lazy loading defers them until they scroll into view.
>
> 1. Add loading="lazy" to images below the fold — but never to the hero/LCP image.
> 2. WordPress adds it by default since 5.5; check your theme or slider has not removed it.

**3. Builder and theme CSS and JavaScript.** Page builders load their frameworks, icon fonts and animation libraries, often in the `<head>`. Turn on the builder's performance options (optimised asset loading, per-page CSS), remove entrance animations from the first screen, and use your caching plugin's defer and unused-CSS options one at a time. The [Elementor](https://getreport.app/guides/elementor-performance-asset-loading-fonts-dom) and [Divi](https://getreport.app/guides/divi-performance-settings) guides have the settings.

> **Check: Page builder weight.** A page builder ships its whole framework on every page, whatever the page uses, and wraps every element in extra containers. When it becomes most of the code and most of the markup the visitor downloads and the browser lays out, every other speed fix has less to work with.
>
> 1. Switch on the builder's own performance settings first: see the report for the exact setting
> 2. Remove widgets, animations and add-on packs the page does not use; each one adds its own CSS and JavaScript.
> 3. For the pages that matter most (home, key landing pages) consider building them with core blocks and the theme alone, and keep the builder for the rest.

**4. Web fonts.** A headline that waits for a Google Font delays LCP when the headline is the largest text. Host fonts locally (most themes and builders have a setting), limit the weights, and use `font-display: swap`.

The caching plugin guides cover the switches tab by tab: [WP Rocket settings for Core Web Vitals](https://getreport.app/guides/wp-rocket-settings-for-core-web-vitals) and [LiteSpeed Cache settings for Core Web Vitals](https://getreport.app/guides/litespeed-cache-settings-for-core-web-vitals).

## INP on WordPress

INP fails when the page is busy running JavaScript at the moment a visitor taps. On WordPress, that JavaScript comes from a predictable list:

- **Page builder widgets** (tabs, accordions, carousels, animations) and the frameworks behind them.
- **Plugins that load everywhere:** sliders, pop-ups, social sharing, related posts, forms loaded on pages without a form.
- **Third-party scripts:** tag managers with many tags, chat widgets, heatmaps, A/B testing, ad scripts.
- **WooCommerce extras:** cart fragments, product filters, variation swatches and upsell widgets, especially on category pages.

The fixes, in order: remove plugins and tags that do not earn their place; stop the rest from loading on pages that do not use them (plugin settings, or an asset manager); delay third-party scripts until the first interaction with your caching plugin, excluding anything the first screen needs, such as the menu or the cookie banner; and move tracking into one tag manager container you keep lean.

> **Check: WordPress plugin weight.** Every active plugin can add scripts and styles to every page, whether the page uses them or not. A slider or a form builder can weigh more than the rest of the site together.
>
> 1. Deactivate plugins the site does not use; for the heavy ones in the table, check whether a lighter alternative exists.
> 2. Load plugin assets only where needed with a performance plugin (Perfmatters, Asset CleanUp) or the plugin's own "load on demand" setting.

> **Check: Third-party code weight.** Tags, widgets and embeds from other companies run on your visitors' phones at your page's expense. Over 250 KB or 250 ms of blocking is a sign they dominate the load.
>
> 1. List what each third party gives you; remove the ones nobody looks at.
> 2. Load the rest after interaction or with a facade (a static thumbnail for YouTube, a click-to-load chat button).
> 3. Move tags into a tag manager that fires them late, not in <head>.

If the lab's Total Blocking Time is low but field INP is poor, the slow interaction happens later: opening the mobile menu, filtering products, adding to cart. Record it in Chrome's developer tools → Performance panel and look for the plugin script in the long task. [Fix Interaction to Next Paint](https://getreport.app/guides/fix-interaction-to-next-paint) explains how. On shops, [WooCommerce cart fragments](https://getreport.app/guides/woocommerce-cart-fragments-the-ajax-call-on-every-page) is a frequent culprit.

> **Check: No cart-fragments request on this page.** cart-fragments.js fires a wc-ajax=get_refreshed_fragments request to keep the mini-cart count fresh. Since WooCommerce 7.8 it loads only with the Mini-Cart widget or block; here it still loads on a page that is not the cart, often because a theme or plugin enqueues it. The request bypasses the page cache, so every visit costs a PHP request, and it delays the page for a feature most pages do not show.
>
> 1. Disable cart fragments on pages that are not the cart or checkout. WooCommerce has no setting for it: use the "Disable cart fragments" option in Perfmatters or a similar performance plugin, or a small snippet that dequeues wc-cart-fragments outside the cart, checkout and account pages.
> 2. If the header shows a live cart count, load the count from a lightweight endpoint on cart changes only.

## CLS on WordPress

WordPress layout shifts usually come from something added by a plugin or the theme above the content:

- **Cookie consent banners and notice bars** inserted at the top of the page, pushing everything down. Configure them as an overlay at the bottom of the screen.
- **Ads and embeds** (AdSense, YouTube, social posts) without a reserved height. Give their containers a `min-height`.
- **Images in builder sections without dimensions.** Core adds `width` and `height` to content images, but builder widgets and theme templates do not always. The image findings list images missing them.
- **Web fonts swapping** from the fallback to the theme font and reflowing text. Match the fallback size or preload the main font; see [web fonts without layout shift](https://getreport.app/guides/web-fonts-without-layout-shift).
- **Lazy-loaded content above the fold** that expands when it loads, such as a slider whose height is only known after its script runs. Give the slider a fixed aspect ratio.

> **Check: Every image declares width and height.** Without width and height the browser cannot reserve space, so the text jumps when each image arrives. That is the most common cause of a poor Cumulative Layout Shift score.
>
> 1. Add width and height attributes with the image's real proportions; CSS can still scale it.
> 2. In WordPress, recent versions add them automatically for images inserted through the editor; hard-coded theme images need them by hand.

> **Check: Web fonts show text while loading.** Without font-display, browsers show blank text for up to 3 s while a web font downloads. Visitors stare at empty headings.
>
> 1. Add font-display swap (or optional) to every @font-face rule.
> 2. For Google Fonts, append &display=swap to the stylesheet URL; self-hosted fonts get it in the @font-face block.
> 3. Preload the one or two fonts used above the fold.

[Fix Cumulative Layout Shift](https://getreport.app/guides/fix-cumulative-layout-shift) has the CSS for each pattern.

## Hosting and Core Web Vitals

Hosting mostly affects LCP, through the first byte, and it sets a floor no front-end work can go below. The signs that the host is the limit: cached pages still answer slower than 600 ms from nearby, or the first byte swings widely during busy hours. Before moving, compare hosts with your own measurements; [choosing a WordPress host by measured TTFB](https://getreport.app/guides/choosing-a-wordpress-host-by-measured-ttfb) shows how. A CDN in front helps visitors far from the server, once the page cache works.

## Confirm the result

Lab numbers move as soon as you clear the cache and re-test. The real-visitor numbers that decide the assessment cover 28 days, so they catch up over about four weeks.

> **Free tool:** [Core Web Vitals report: 40 weeks of CrUX history](https://getreport.app/tools/cwv-history): Free Core Web Vitals report with up to 40 weeks of history: LCP, INP and CLS week by week from the Chrome UX Report, to spot the release that broke it.

The Core Web Vitals report tool plots up to 40 weeks of Chrome UX Report data for your site or a popular page against the thresholds. A plugin update, a new builder version or a new tag often shows up as the week a line crossed into "poor", which tells you what to look at. For the general plan when more than one metric fails, see [how to improve Core Web Vitals](https://getreport.app/guides/how-to-improve-core-web-vitals).

## Common mistakes

- **Installing a second optimisation plugin** to fix what the first one broke.
- **Lazy-loading every image,** including the first slide or hero, often through a plugin setting that overrides core.
- **Testing while logged in,** which bypasses the page cache and adds the admin bar.
- **Delaying all JavaScript** without exclusions, so the menu or cookie banner stops working until the visitor taps.
- **Fixing the home page only** while product, post and archive templates fail.
- **Blaming WordPress** for what a builder, slider or tag manager sends.

## Questions people ask

### Can a WordPress site pass Core Web Vitals?

Yes. WordPress core includes lazy loading, fetch priority for the likely LCP image, image dimensions and speculative loading, and many WordPress sites pass all three metrics. Failures usually come from what is added on top: no page cache or slow hosting, a heavy page builder, plugins loading scripts on every page, lazy-loaded hero images and cookie banners that push content. Fix those and WordPress is not the limit.

### Do page builders make Core Web Vitals fail?

They make it harder, mostly for LCP and INP. Builders such as Elementor and Divi load their own CSS, JavaScript and icon fonts and wrap content in extra HTML, which delays rendering and adds main-thread work. Turning on their performance settings, removing animations from the first screen and limiting widgets usually brings pages into the good range. The block editor starts with less code.

### Which WordPress plugins hurt INP the most?

The ones that run JavaScript on every page: sliders and carousels, pop-up and opt-in tools, social sharing buttons, chat widgets, heatmaps, A/B testing, ad scripts and tag managers with many tags. On shops, product filters, swatches and cart fragments add more. A plugin detector that measures each plugin's scripts shows which ones to remove, restrict to certain pages or delay until the visitor interacts.

### Is a caching plugin enough to pass Core Web Vitals on WordPress?

Usually not on its own. A page cache fixes the server part of LCP, and settings like deferring JavaScript and removing unused CSS help more. But a caching plugin cannot shrink an oversized hero image uploaded at camera size, remove a heavy plugin, or stop a cookie banner from pushing the page down. Use one caching plugin well, then fix images, plugins and layout shifts.

### Why do WordPress sites often fail CLS on mobile?

Because the things that shift content are more visible on a small screen: cookie banners and notice bars inserted at the top, ads and embeds without reserved height, sliders whose height is set by JavaScript, and web fonts that reflow narrow columns of text. Overlay banners at the bottom, give ad and slider containers fixed dimensions, and match the fallback font to the web font.
