
WordPress Core Web Vitals problems are the most common reason site owners email me after a redesign: the site looks fine, but Search Console shows a wall of “poor” URLs, PageSpeed Insights disagrees with itself, and nobody can explain what LCP, INP and CLS actually mean for a WordPress site. The frustrating part is that the three metrics fail for different reasons and need different fixes – treating them as one “speed problem” is why so many optimisation attempts change nothing in Google’s data.
This guide is a metric-by-metric repair manual: what Core Web Vitals are and how Google really uses them, the exact thresholds, how to measure without fooling yourself, and then a dedicated fix section for each of LCP, INP and CLS with the specific WordPress causes I see again and again. I have run this process on hundreds of the 500+ WordPress sites I have built or fixed over 12+ years, for clients in Germany, the UK, the US and Australia, so the numbers and expectations here come from real projects, not lab demos. For the broader basics – hosting, caching, image formats in general – see my complete WordPress speed guide; this article stays focused on the three metrics themselves.
Table of contents
- What Core Web Vitals are and how Google uses them
- The thresholds: good, needs improvement, poor
- How to measure properly (and why lab scores mislead)
- Fixing LCP: the loading metric
- Fixing INP: the responsiveness metric
- Fixing CLS: the stability metric
- The plugin and theme reality check
- A prioritised fix order that actually works
- How long until Google notices your fixes
- Realistic before and after numbers from client work
- Frequently asked questions
What Core Web Vitals are and how Google uses them
Core Web Vitals are three user-experience measurements that Google collects from real Chrome users and uses as part of its page experience ranking signals. Each one answers a different question:
- LCP (Largest Contentful Paint) – how quickly does the biggest visible element (usually a hero image or headline) appear? This is the “is it loading?” metric.
- INP (Interaction to Next Paint) – when the visitor taps a menu, clicks a button or types in a field, how long until the screen visibly responds? This is the “is it frozen?” metric.
- CLS (Cumulative Layout Shift) – how much does the page jump around while loading? This is the “did the button move just as I tapped it?” metric.
Field data vs lab data
This distinction decides whether your optimisation work is real or theatre. Field data is collected from actual visitors through the Chrome User Experience Report (CrUX): every opted-in Chrome user who loads your page contributes their measured LCP, INP and CLS, on their real phone, on their real network. Lab data is a single simulated load – Lighthouse running on a throttled connection in a data centre. Google’s ranking systems only ever see field data. A Lighthouse score of 98 means nothing to Google if real visitors on mid-range Android phones experience a 4-second LCP.
The 75th percentile rule
Google does not use your average. For each metric, it takes the 75th percentile of all recorded visits over the last 28 days: your page passes LCP only if at least 75% of visits had a good LCP. This is why a site can “feel fast” to you on a fibre connection and an iPhone and still fail – the visitor on a EUR 150 Android phone on 4G in a train is inside that 75th percentile, and you are probably not. It also means one slow template can drag a whole URL group down while your home page looks fine.
How much does it matter for rankings?
Honest answer: it is a real but modest ranking signal – content and relevance still dominate. But the indirect effects are larger than the direct one. Pages that fail INP lose taps; pages that fail CLS lose form submissions; a slow LCP raises bounce rate, and on WooCommerce stores I have measured conversion differences of 10-20% between a failing and a passing checkout path. Treat Core Web Vitals as a user-experience budget that happens to also please Google, and the effort always pays for itself.
The thresholds: good, needs improvement, poor
Google publishes exact thresholds, applied at the 75th percentile. Memorise the “good” column – it is the only target that matters:
| Metric | What it measures | Good | Needs improvement | Poor |
|---|---|---|---|---|
| LCP | Time until the largest visible element renders | ≤ 2.5 s | 2.5 – 4.0 s | > 4.0 s |
| INP | Delay between an interaction and the next screen update | ≤ 200 ms | 200 – 500 ms | > 500 ms |
| CLS | Total unexpected layout movement during the visit | ≤ 0.1 | 0.1 – 0.25 | > 0.25 |
Two notes on reading these. First, CLS is a unitless score, not a time – 0.1 roughly means the shifting content moved by about 10% of the viewport. Second, “needs improvement” is a fail for practical purposes: Search Console only marks a URL group as good when all three metrics are good, and a 2.6-second LCP gets the same treatment as a 3.9-second one in the pass/fail sense. Aim comfortably under the threshold – I target LCP around 1.8-2.0 s in field data so normal variance never tips a page over.
How to measure properly (and why lab scores mislead)
PageSpeed Insights: read the top section first
Run your URL through PageSpeed Insights and look at the top block, “Discover what your real users are experiencing”. That is CrUX field data – the numbers Google actually uses. The Lighthouse score below it is lab data from one simulated load. The two disagree constantly, in both directions: I regularly see sites with a lab score of 60 that pass all three vitals in the field (heavy but well-ordered pages), and sites scoring 95 in the lab that fail INP badly (because Lighthouse’s simulated interaction cannot reproduce what happens when a real user opens a mega-menu built by a page builder). If the field section says “no data”, your page does not have enough Chrome traffic for its own entry – check the origin-level data instead, and rely more on the lab diagnostics as hints.
Search Console: the Core Web Vitals report
Search Console > Experience > Core Web Vitals is where you track progress. It groups similar URLs (all product pages, all blog posts) and tells you which group fails which metric. This grouping is a gift: fix the template, and dozens or hundreds of URLs move together. Click into a failing group to see example URLs, then diagnose those in PageSpeed Insights.
Chrome DevTools: the Performance panel
For INP and CLS you need DevTools. Open the Performance panel, switch on CPU throttling (4x slowdown to simulate a mid-range phone), record a load, and interact with the page. Long grey-yellow blocks on the main thread are long tasks – anything over 50 ms delays interactions. The panel also has a dedicated layout shift track that shows exactly which element jumped and when. The free Web Vitals Chrome extension is a lighter option: it shows live LCP, INP and CLS values as you browse your own site, including which element was the LCP and which interaction was slowest.
Test on a real cheap phone
The most honest test costs nothing: open your site on a two-year-old mid-range Android phone over mobile data, not office Wi-Fi. Tap the menu, scroll, open a product page. If it stutters, your INP is failing regardless of what any dashboard says. I keep an old Android device on my desk purely for this, and it has settled more arguments with lab scores than any tool.

Fixing LCP: the loading metric
Step 1: find your LCP element
You cannot fix LCP without knowing which element it is. PageSpeed Insights names it under the “Largest Contentful Paint element” diagnostic, and the Web Vitals extension highlights it live. On most WordPress sites it is the hero image, a background image on the header section, or the H1 on text-led pages. On WooCommerce product pages it is almost always the featured product image. Once you know the element, LCP becomes a simple question: what is delaying this one element?
The four WordPress LCP killers
- Slow TTFB (hosting and no page cache). If the server takes 1.5 s to send the first byte, a 2.5-second LCP is already nearly impossible. Cheap shared hosting, no server-level caching, and bloated themes that run 100+ database queries per load are the usual causes. TTFB should be under 200 ms cached, under 600 ms worst case.
- Render-blocking CSS. WordPress happily loads every plugin’s stylesheet in the head. The browser cannot paint anything until all of it arrives, so 15 stylesheets from 12 plugins push LCP back by seconds on mobile.
- Late-discovered hero images. If the hero is a CSS background image, or is injected by a slider or builder script, the browser only discovers it after downloading and running CSS or JS – the image starts downloading at second 2 instead of second 0. This is the single most common LCP bug I find in page-builder sites.
- Oversized images. A 2400px, 900 KB JPEG served to a 390px-wide phone screen. Still everywhere in 2026.
The fixes, in order of impact
- Fix the server first. Decent hosting (from around EUR 10-25/month – LiteSpeed or a managed WordPress host), plus full-page caching (LiteSpeed Cache, WP Rocket, or the host’s own layer) so repeat and bot-measured loads skip PHP entirely. Add object caching (Redis) on WooCommerce sites where pages cannot always be cached. This step alone often moves LCP by a full second.
- Make the hero an early-discovered, prioritised image. A real
<img>in the HTML, not a CSS background; addfetchpriority="high"to it and make sure it is NOT lazy-loaded (WordPress lazy-loads by default – the first image above the fold must be excluded). If the theme forces a background image, preload it:<link rel="preload" as="image" href="/wp-content/uploads/hero.webp" fetchpriority="high"> - Serve modern formats at the right size. WebP (or AVIF) with proper
srcsetsizes; the hero should arrive as 100-200 KB, not 900. Converter plugins or server-level conversion both work – details in the speed guide. - Deal with render-blocking CSS. Generate critical CSS (WP Rocket and LiteSpeed Cache both do this) so above-the-fold styles are inlined and the rest loads asynchronously, and remove stylesheets of plugins that do not run on that page at all.
- Preconnect to essential third-party origins (fonts, a CDN) so their connections are warm before they are needed – but only two or three; preconnecting to ten origins hurts.
On a typical neglected WordPress site, steps 1-3 take LCP from 4-5 s to around 2 s. Step 4 is where it drops to 1.5 s and under.
Fixing INP: the responsiveness metric
What replaced FID, and why it is harder
INP replaced First Input Delay in March 2024, and it is a much stricter metric. FID only measured the delay before the browser started handling your first interaction – most sites passed it without trying. INP measures the full time from any interaction to the next visual update, across the whole visit, and reports one of the worst ones. A site that passed FID with 40 ms can fail INP with 600 ms, and this is exactly what happened to thousands of WordPress sites overnight: INP is now the metric WordPress sites fail most, and it is almost always a JavaScript problem.
What causes bad INP in WordPress
- Page-builder JavaScript. Elementor, Divi and friends ship large scripts that attach handlers to everything. Opening a mobile menu can trigger hundreds of milliseconds of main-thread work. This is a real, structural cost of builders – I covered the trade-off in custom development vs page builders.
- Long tasks from plugins. Any task over 50 ms blocks interactions. Analytics wrappers, chat widgets, popup plugins, “smart” related-posts engines – each adds tasks, and they queue behind each other.
- Third-party tags, especially Google Tag Manager. A GTM container that has accumulated 30 tags over five years is an INP disaster: every click fires listeners, and marketing pixels run heavy code at exactly the moment the user interacts.
- Hydration in “modern” themes. Some React-based themes and headless setups re-render the entire page on load; interactions during hydration wait for all of it.
How to find your slow interactions
PageSpeed Insights tells you INP is failing but not which interaction. The Web Vitals extension (with “console logging” enabled) names the element and the script attribution for every slow interaction as you click around. DevTools Performance panel with 4x CPU throttling shows you the long task behind it – expand it and you see which script the time went to. Test the interactions users actually perform: mobile menu, search, add to cart, filters, form fields. On WooCommerce sites the add-to-cart and checkout fields are the interactions that matter commercially – more on that in my WooCommerce optimisation tips.
The fixes
- Remove JavaScript before optimising it. Audit every plugin: each one that prints scripts on every page needs to justify itself. Deactivating an unused slider, popup or social plugin is worth more than any code-splitting trick.
- Defer what remains. Delay non-critical scripts until interaction or idle time (WP Rocket’s “delay JavaScript execution”, Flying Scripts, or LiteSpeed Cache can do this). Analytics and pixels do not need to run in the first 200 ms.
- Clean up Tag Manager. Export the container, list the tags, delete the dead campaigns – most containers I audit lose half their tags with zero business impact. Fire the rest on a delayed trigger, not on page load.
- Break long tasks in custom code. If your own code does heavy work in a handler, yield to the main thread between chunks (
setTimeoutorscheduler.yield()) and give instant visual feedback first (open the menu, then compute). - Consider the structural fix. If a builder theme has an INP of 500+ ms after all of the above, the honest answer is that the platform is the problem. A lean custom theme has 10-20 KB of JavaScript instead of 500+ KB, and INP stops being a topic entirely.
Fixing CLS: the stability metric
The four causes on WordPress sites
- Images without dimensions. If an
<img>has nowidthandheightattributes, the browser reserves zero space, and the content below jumps down when the image arrives. Modern WordPress adds the attributes automatically, but hand-written HTML, old themes and some builders still omit them. - Injected content: cookie banners, notification bars, ads. A consent banner that inserts itself at the top of the page and pushes everything down is the classic CLS bomb. Ad slots that load late and expand are the same problem on content sites.
- Web fonts (FOUT). The page renders in a fallback font, the web font arrives with different letter widths, every line of text reflows, headlines wrap differently, and the whole page shifts.
- Sliders and animated hero sections. Carousels that resize to their tallest slide after initialisation, or builder sections that animate height on load.
The fixes
- Give every image dimensions.
widthandheightattributes (oraspect-ratioin CSS) on every image, logo and embed. This is a one-line fix per template and usually eliminates half the score. - Reserve space for anything injected. Overlay the cookie banner at the bottom of the viewport (position fixed) instead of pushing content; give ad slots and embed containers a fixed
min-heightso the space exists before the content does. - Fix the fonts. Host fonts locally, preload the one or two files used above the fold, and set
font-display: swapwith a fallback font that is metrically close (adjust withsize-adjustif needed):<link rel="preload" as="font" type="font/woff2" href="/fonts/inter-var.woff2" crossorigin>Better yet, use fewer font files – one variable font covers most sites.
- Fix or remove the slider. Set an explicit height on the carousel container. Or ask the harder question: sliders hurt LCP, INP and CLS at once and nobody clicks slide three – a static hero is faster on all three metrics.
- Animate with transform, not layout. Entrance animations that change
height,marginortopshift the layout;transformandopacitydo not count against CLS.
CLS is usually the most mechanical of the three to fix – a day of template work gets most sites from 0.3 to under 0.05. The DevTools layout shift track shows you each shift with the exact element highlighted, so there is no guesswork.

The plugin and theme reality check
Here is the pattern across nearly every Core Web Vitals project I take on: the biggest wins come from removing things, not adding them. Site owners arrive having installed two caching plugins, an image optimiser, an “asset cleanup” tool and a “defer everything” snippet from a forum – five additions trying to compensate for forty plugins and a 3 MB theme. The stack fights itself, and the field data has not moved in months.
The audit that actually works is subtraction. List every plugin and ask: what does this do for the visitor, and what does it cost on every page load? In a typical audit of a site with 45 plugins, I find 10-15 that are deactivated-but-installed, abandoned by their developers, duplicating each other, or serving a feature nobody has used since 2022. Removing them improves all three metrics at once and reduces the security surface as a side effect – plugin sprawl is a maintenance problem as much as a performance one, which is why performance review is part of my maintenance and security plans and why my maintenance checklist includes a quarterly plugin audit.
The same logic applies to the theme. A multipurpose theme with a bundled builder starts every page 300-500 KB of CSS and JavaScript behind a lean theme, before you add any content. You can claw some of it back with optimisation plugins, but you are optimising bloat rather than removing it. When a client is planning a redesign anyway, moving to a custom-coded theme is the one decision that makes all three metrics easy instead of a permanent struggle – the sites I build pass Core Web Vitals on launch day without a single optimisation plugin.
A prioritised fix order that actually works
Doing the fixes in the wrong order wastes effort – critical CSS tuning on a 1.5-second TTFB is polishing a slow server. This is the sequence I use on every project:
- Measure first (half a day). Field data from PageSpeed Insights and Search Console per URL group; identify the LCP element, the slowest interaction and the shifting elements. Write the numbers down – you need the before.
- Hosting and TTFB (day 1). Page caching working and verified, PHP 8.2+, object cache if WooCommerce, host upgrade if TTFB stays over 600 ms. Nothing else matters until this is right.
- LCP (days 1-2). Hero image format, size, priority and discovery; critical CSS; unused assets removed. LCP moves fastest and matters most – it is the metric visitors feel as “slow”.
- CLS (day 2-3). Dimensions, font loading, banner behaviour, slider heights. Mechanical, predictable, satisfying.
- INP (days 3-5). Plugin audit and removals, script delaying, GTM cleanup, then the long-task work. INP comes last not because it matters least but because the earlier steps (fewer plugins, fewer scripts) have already improved it, and what remains is the genuinely hard part.
Budget roughly 3-5 working days for a business site, 5-8 for a WooCommerce store. At my rate of EUR 15 per hour that is a EUR 400-900 project in most cases – I quote a fixed price within 24 hours after seeing the field data.
How long until Google notices your fixes
This is the question every client asks in week one, so let me set the expectation: CrUX field data is a rolling 28-day window. When you fix LCP today, tomorrow’s field number still contains 27 days of slow visits. The metric improves gradually as old days fall out of the window, and only after a full 28 days does the data purely reflect the fixed site. Search Console then needs to re-evaluate the URL group, so “Good” status typically lands 4-6 weeks after the work is done.
How to survive the wait without flying blind: verify the fixes immediately with lab tools and the Web Vitals extension (your own measured LCP on a throttled connection should already be under 2 s the day you finish), then watch the field 75th percentile drift down week by week in PageSpeed Insights. In Search Console, use the “validate fix” button on the failing group – it does not speed anything up, but it tracks the re-evaluation for you. What you should not do is keep changing things during the window because “it has not worked yet”; you will never know which change did what. Fix, verify in the lab, then leave it alone for four weeks.
Realistic before and after numbers from client work
So you can calibrate expectations, here are three anonymised but typical projects from the last couple of years:
- A German consultancy on a multipurpose theme with Elementor: LCP 4.6 s, INP 490 ms, CLS 0.31 at the 75th percentile. Work: host move, page cache, hero image rebuilt as a prioritised WebP, 14 plugins removed, GTM cut from 26 tags to 9, fonts localised. After the 28-day window: LCP 1.9 s, INP 210 ms, CLS 0.04. INP only fully passed (170 ms) after a later template rebuild replaced the heaviest builder sections – the honest limit of optimising a builder site.
- A UK WooCommerce store, ~800 products: LCP 3.8 s, INP 350 ms, CLS 0.12. Work: Redis object cache, product image srcset fixed, checkout scripts trimmed, review-widget third party replaced with native reviews. Result: LCP 2.1 s, INP 160 ms, CLS 0.03 – and a measurable lift in checkout completion, which is what the client actually cared about.
- An Australian blog on a lean custom theme I built: passed everything from launch (LCP 1.4 s, INP 80 ms, CLS 0.01) with no optimisation plugins installed. I include this not to boast but to make the point from the reality-check section: when the foundation is light, Core Web Vitals is not a project, it is a non-event.
What I do not promise: instant rankings jumps. Passing Core Web Vitals removes a negative signal and improves conversion; it does not replace content. Any freelancer promising “position 1 from speed alone” is selling something else.
Need help fixing your Core Web Vitals?
I offer this exact process as a fixed-price service: field-data audit, prioritised fixes for LCP, INP and CLS, before/after numbers, and a plain-English report of what was changed and why. See the WordPress speed optimisation service and my portfolio, or send me a message with your URL – I will look at your field data and reply with a quote within 24 hours.
Frequently asked questions
What are WordPress Core Web Vitals?
They are Google’s three user-experience metrics – LCP (loading), INP (responsiveness) and CLS (visual stability) – measured on real visitors to your WordPress site via Chrome and used as a ranking signal. A page passes when the 75th percentile of visits meets all three thresholds.
What are the Core Web Vitals thresholds?
Good means LCP of 2.5 seconds or less, INP of 200 milliseconds or less, and CLS of 0.1 or less, each measured at the 75th percentile of real visits over 28 days.
Why does my site pass PageSpeed Insights but fail in Search Console?
PageSpeed’s Lighthouse score is lab data from one simulated load; Search Console uses field data from real visitors. Google ranks on the field data, so trust that and treat the lab score only as a diagnostic tool.
What is a good INP for WordPress?
200 ms or less at the 75th percentile. Most failures come from heavy JavaScript – page builders, plugin sprawl and overloaded Tag Manager containers – so removal and deferral are the main fixes.
Do plugins fix Core Web Vitals?
A caching plugin and an image optimiser genuinely help LCP, but no plugin can remove the JavaScript another plugin adds. The largest improvements come from removing plugins and heavy theme features, then optimising what remains.
How long until Core Web Vitals improve after fixes?
Field data is a rolling 28-day window, so expect gradual improvement over four weeks and a “Good” status in Search Console roughly 4-6 weeks after the fixes. Verify immediately with lab tools so you know the work is done.
Can Elementor or Divi sites pass Core Web Vitals?
Yes, with disciplined optimisation – good hosting, trimmed plugins, delayed scripts – but they start with a large handicap, and INP is often the sticking point. A lean custom theme passes with far less ongoing effort.