To improve Core Web Vitals on a WordPress site, first find out which metric fails (LCP, INP or CLS) and on which page templates, using field data from PageSpeed Insights and Search Console. Then break the problem down with Chrome’s tools, fix the specific cause (server, main image, JavaScript, layout) and validate over 28 days. Each metric has its usual suspects on WordPress, and this guide walks through them one by one.
Guide current as of 15 October 2026, checked against WordPress 7.1 and Google’s documentation on web.dev.
Key takeaways
- A page is rated good when, at the 75th percentile of visits, LCP ≤ 2.5 s, INP ≤ 200 ms and CLS ≤ 0.1. Mobile and desktop are assessed separately.
- Diagnose before you fix: LCP splits into four sub-parts and INP into three phases, and each one points to a different cause.
- On WordPress, the usual culprits are high TTFB, a lazy-loaded hero image, heavy JavaScript (page builders, third-party scripts) and content injected without reserved space (banners, ads, web fonts).
- Core already does part of the job: automatic
fetchpriority="high"since 6.3,sizes="auto"since 6.7, speculative loading since 6.8. - After a fix, allow 28 days for field data to catch up, and start a validation in Search Console.
What are Core Web Vitals and why do they matter?
Core Web Vitals are three Google metrics that describe what real visitors experience: LCP (how fast the main content shows), INP (how quickly the page responds to interactions) and CLS (how stable the layout is). They are collected from Chrome users and used, among many other signals, by Google’s ranking systems.
Google’s documentation on page experience is careful here: Core Web Vitals are used by its ranking systems, but there is no single page experience signal and good scores do not guarantee top rankings. They matter first and foremost to your visitors.
| Metric | What it measures | Good | Needs improvement | Poor |
|---|---|---|---|---|
| — | — | — | — | — |
| LCP (Largest Contentful Paint) | Render time of the largest visible element | ≤ 2.5 s | 2.5–4 s | > 4 s |
| INP (Interaction to Next Paint) | Delay between an interaction and the next frame | ≤ 200 ms | 200–500 ms | > 500 ms |
| CLS (Cumulative Layout Shift) | Unexpected layout movement | ≤ 0.1 | 0.1–0.25 | > 0.25 |
Where do you find your Core Web Vitals data?
Start with field data from real visitors: PageSpeed Insights for a single URL, and the Core Web Vitals report in Search Console for the whole site. Lab tools such as Lighthouse then help you reproduce and diagnose issues, but they never replace field data.
| Tool | Data | Best used for |
|---|---|---|
| — | — | — |
| PageSpeed Insights | Field (Chrome UX Report, previous 28 days) + lab | Checking one URL and its origin |
| Search Console, Core Web Vitals report | Field, grouped similar URLs | Spotting failing templates, validating fixes |
| CrUX Vis | Field, weekly history | Tracking an origin over time (replaces the old Looker Studio dashboard) |
| Chrome DevTools, Performance panel | Live local metrics | Finding the LCP element, timing each interaction |
| web-vitals JavaScript library | Field, your own visitors | Collecting metrics with detailed attribution |
Two common traps: Search Console gives each URL group the status of its worst metric (a group marked Poor because of CLS may have an excellent LCP), and small sites often lack enough Chrome traffic for URL-level data, in which case PageSpeed Insights falls back to origin-wide data.
How do you diagnose a slow LCP?
Identify the LCP element (usually the featured image, a banner or the main heading), then measure its four sub-parts: server response time, the delay before the resource starts loading, the load itself, and the render delay. The longest sub-part tells you what to fix.
Google’s Optimize LCP guide describes this method and suggests a rough split for a healthy LCP:
| Sub-part | What it covers | Rough share of LCP | Typical WordPress cause |
|---|---|---|---|
| — | — | — | — |
| TTFB | Server response for the HTML document | About 40% | No page cache, overloaded hosting, slow PHP, redirects |
| Resource load delay | Time before the browser starts fetching the LCP image | Under 10% | loading="lazy" on the hero, CSS background image, slider injecting images with JavaScript |
| Resource load duration | Downloading the image itself | About 40% | Oversized image, unoptimised JPEG or PNG |
| Element render delay | From download complete to paint | Under 10% | Render-blocking CSS or JavaScript, web font not loaded, fade-in animation |
Open DevTools > Performance in Chrome: live metrics show your local LCP and its element, and a page-load recording breaks down the sub-parts.
1. High TTFB: fix the server first
If TTFB alone eats half your budget, no front-end tweak will save you. Make sure pages are served from a page cache (on a LiteSpeed server, the LiteSpeed Cache plugin drives the built-in cache: see our LiteSpeed Cache setup guide), that PHP is up to date and that no needless redirect chain sits in front of the page. The web server matters too, as our comparison of LiteSpeed, Nginx and Apache for WordPress explains.
# Measure TTFB in seconds (run twice to test a warm cache)
curl -s -o /dev/null -w "TTFB: %{time_starttransfer}\n" https://www.example.com/2. Load delay: make the LCP image discoverable and high priority
The LCP image should be in the initial HTML, without loading="lazy", ideally with fetchpriority="high". Since WordPress 6.3, core adds that priority to the image it expects to be the LCP element and stops lazy-loading the first content images, as the official dev note explains. Problems therefore usually come from a theme, page builder or optimisation plugin that lazy-loads every image again.
If your theme outputs the hero image itself, you can force the right behaviour:
// Above-the-fold featured image: never lazy-loaded, high priority.
echo wp_get_attachment_image(
get_post_thumbnail_id(),
'large',
false,
array(
'loading' => false,
'fetchpriority' => 'high',
)
);In LiteSpeed Cache, exclude the logo and header image from lazy loading, or turn on Viewport Images (VPI). Avoid hero sliders: their first image is often injected by JavaScript and discovered late.
3. Load duration: make the image lighter
Serve the image at the size it is actually displayed (WordPress generates several sizes and a srcset attribute for exactly this), compressed and in a modern format such as WebP or AVIF.
4. Render delay: clear the rendering path
If the image has downloaded but paints late, look for what blocks rendering: large CSS files in the <head>, synchronous scripts, a scroll-reveal animation on the hero block, or a heading waiting for a web font. Minify and defer JavaScript and keep animations for content further down.
How do you fix a high INP?
A high INP means the browser takes too long to respond to a click, tap or keystroke. Find the slow interaction, measure its three phases (input delay, processing, presentation), then cut the JavaScript keeping the main thread busy: heavy plugins and builders, third-party scripts, expensive event handlers.
INP reports the slowest interaction of the visit (ignoring the worst one per 50 interactions on very interactive pages). According to Optimize INP, each interaction breaks down like this:
| Phase | What happens | Typical WordPress cause | Fix |
|---|---|---|---|
| — | — | — | — |
| Input delay | Main thread busy when the user clicks | Scripts running during load (builder, chat, ads, analytics) | Defer non-essential scripts, remove some, load them after consent |
| Processing duration | Event handlers run | Heavy menus, filters, tabs or add-to-cart code; several plugins reacting to one click | Split work into shorter tasks, do only what the next frame needs |
| Presentation delay | Layout and paint of the result | Very large DOM (deeply nested builder containers), style recalculations | Slim the DOM, use content-visibility on off-screen sections |
To find the culprit, open DevTools > Performance and interact with the page: the interactions log shows each one’s duration and phases. Turn on CPU throttling to get closer to a budget phone. To see what real visitors experience, the official web-vitals library can report the cause of every slow interaction:
import { onINP } from 'web-vitals/attribution';
onINP( ( metric ) => {
// metric.value: duration in ms; metric.attribution: target element and phase timings.
console.log( 'INP', metric.value, metric.attribution );
} );Any JavaScript task over 50 ms is a long task that blocks interactions. If you build your own theme, yield to the browser between steps of long work (scheduler.yield() where supported, setTimeout otherwise). With off-the-shelf plugins, most of the gain comes from removing what you do not need.
Be wary of “delay all JavaScript until interaction”: it flatters the lab score but can pile every script onto the first click and hurt real-world INP. Test it page by page.
How do you eliminate layout shifts (CLS)?
CLS measures elements that move without the user doing anything. Reserve space for everything that arrives after the first paint: image and iframe dimensions, ad slots and banners, and web fonts whose metrics match the fallback font. Never insert content above what the visitor is already reading.
Typical WordPress causes, based on Google’s Optimize CLS guide:
- Images and videos without
widthandheight, common in hand-pasted HTML and some builder blocks. WordPress adds dimensions to Media Library images; LiteSpeed Cache offers “Add Missing Sizes”. - Cookie banners, announcement bars or notices pushed in at the top after load. Show them as an overlay (fixed position) instead.
- Ads and embeds (videos, maps, social posts): reserve their height with
min-heightoraspect-ratio. - Web fonts swapping in at a different size: use
size-adjustand the metric override descriptors, orfont-display: optionalfor non-essential fonts. - Animating layout properties (
top,height,margin): usetransforminstead.
/* Reserve space for a 16:9 video embed (if your theme doesn't already) */
.wp-block-embed__wrapper {
aspect-ratio: 16 / 9;
}
/* Fallback font tuned to limit the shift when the web font loads */
@font-face {
font-family: "Inter Fallback";
src: local("Arial");
size-adjust: 107%;
}
body {
font-family: "Inter", "Inter Fallback", sans-serif;
}The right size-adjust value depends on your font pair. Also keep pages eligible for the back/forward cache (bfcache): a restored page shows instantly with no shift. An unload handler or a Cache-Control: no-store header prevents it; check eligibility under DevTools > Application > Back/forward cache.
Which WordPress features already help Core Web Vitals?
An up-to-date install does a lot already: native lazy loading, high priority for the likely LCP image, sizes="auto" on lazy images and speculative loading of the next page. Your main job is not to undo these optimisations.
| Version | Core Web Vitals improvement | Metric |
|---|---|---|
| — | — | — |
| WordPress 5.5 | Native loading="lazy" on images with dimensions | LCP (long pages), data |
| WordPress 6.3 | Automatic fetchpriority="high" on the likely LCP image; first 3 content images no longer lazy-loaded | LCP |
| WordPress 6.7 | sizes="auto" on lazy-loaded images | LCP, page weight |
| WordPress 6.8 | Speculative loading (conservative link prefetching) on by default | LCP of the next page |
| WordPress 6.9 | On-demand block styles for classic themes, interactive block scripts at low priority | LCP, render delay |
To go further without code, the official Performance Lab plugin from the WordPress performance team offers features in testing, such as modern image formats or Image Prioritizer (beta), which prioritises the real LCP element based on measurements from actual visitors. Only enable the modules you need.
Speculative loading is configured through a filter. On a well-cached site you can test a more ambitious mode, which makes the next page near-instant at the cost of extra server requests:
// Child theme functions.php or a small custom plugin
add_filter( 'wp_speculation_rules_configuration', function ( $config ) {
if ( is_array( $config ) ) {
$config['mode'] = 'prerender';
$config['eagerness'] = 'moderate';
}
return $config;
} );How do you check that your fixes worked?
Check in the lab and with DevTools live metrics first, on the same pages and under the same conditions as before. Then click “Validate fix” in Search Console: Google monitors the affected URLs for 28 days while field data refreshes.
- Record the starting value (field and lab), on mobile, for one template (home, post, product page).
- Make one change at a time and note the date.
- Purge every cache (plugin, server, CDN) and load the page twice to measure a warm cache.
- Check the page visually (menu, forms, cart).
- Start the validation in Search Console for the affected URL group.
- Come back four weeks later and compare field data in PageSpeed Insights or CrUX Vis.
For a broader list of speed actions, from caching to scheduled tasks, see our guide to speeding up WordPress in 15 steps.
How much does hosting weigh on Core Web Vitals?
TTFB alone makes up a large share of LCP, and it depends on the server first. At Hosterwise, every plan runs on LiteSpeed servers with LSCache, HTTP/3 and free SSL certificates, so cached pages are served without running PHP. The Premium and Boost plans add resources for dynamic sites such as WooCommerce stores. Compare them on our WordPress hosting pricing page, or let us move your site for you with our free migration and measure the difference on your own Core Web Vitals.
Core Web Vitals and WordPress FAQ
Do Core Web Vitals affect my WordPress site’s rankings?
Yes, but moderately. Google says its ranking systems use Core Web Vitals among many other signals, and relevant content comes first. Good scores do not guarantee top positions; poor scores mostly hurt your visitors’ experience.
Why does PageSpeed Insights show a good score but failing Core Web Vitals?
The score out of 100 comes from a one-off lab test on a simulated device. The Core Web Vitals at the top of the report come from real visitors over 28 days. The two can differ, especially for INP, which a lab test cannot measure without real interactions.
Why does Search Console show no data?
The report relies on the Chrome UX Report, which needs a minimum volume of visits from Chrome users. A new or low-traffic site may not have enough. Use lab tests and DevTools instead, or collect your own data with the web-vitals library.
Which WordPress plugin improves Core Web Vitals the most?
There is no magic plugin: it depends on the failing metric. A page cache (LiteSpeed Cache on a LiteSpeed server) cuts TTFB and therefore LCP. Performance Lab complements core for images. For INP, the gains mostly come from removing heavy plugins and scripts.
How long before a fix shows up?
Instantly in lab tests, but about 28 days in field data, which covers a rolling window. Search Console’s validation follows the same timeline.
Is my page builder to blame for poor INP?
Often in part: builders load JavaScript and produce a large DOM, both of which slow interactions down. Disable unused modules, limit animations and nested containers, then measure again.

