Fixing Largest Contentful Paint on WordPress
Find the element Google measures as your LCP, then fix the four things that delay it: server time, render-blocking CSS, image delivery and lazy loading.

In this article
Largest Contentful Paint measures how long it takes for the biggest piece of content in the viewport — usually a hero image or a headline — to appear. Google treats 2.5 seconds or less, measured at the 75th percentile of real visits, as good. It is the Core Web Vital WordPress sites fail most often.
Most LCP advice is a list of plugins to install. That approach treats every slow page as the same problem, and it is not. This guide starts by finding the element being measured and the phase in which its time is lost, so the fix you apply matches the thing that is actually slow.
Finding your LCP element, and why it changes between viewports
Open the page in Chrome, run a Lighthouse or Performance panel recording with mobile emulation, and look for the LCP marker. PageSpeed Insights also names the element under its diagnostics. Do this on mobile first, because that is the measurement Google uses for most sites and it is almost always the worse one.
The element is frequently not the one you would guess. On desktop it may be a wide hero image; on a phone the same image is cropped or hidden and the LCP becomes the heading, a slider's first slide or even a cookie banner's paragraph. Each of those needs a different fix, so note the element per template — home, post, product, category — rather than assuming one answer covers the site.
The four phases of LCP
Chrome breaks LCP time into four parts, and the Performance panel shows them for the measured element. Knowing which part dominates tells you where to work.
- Time to first byte: how long before the server starts sending HTML. Everything else waits for this.
- Resource load delay: the gap between the first byte and the browser starting to download the LCP image. Long delays mean the browser discovered the image late.
- Resource load duration: how long the image itself takes to download, which comes down to file size, format and network.
- Element render delay: the time between the image arriving and it being painted, usually caused by render-blocking CSS, fonts or JavaScript.
Phase one: server response and where hosting really matters
If time to first byte is over about 800 milliseconds on a phone, no amount of front-end work will get you to a good LCP. On WordPress the cure is nearly always full-page caching: serving a stored HTML copy instead of running PHP and dozens of database queries per visit.
Check that the cache actually hits. Response headers from most caching layers say HIT or MISS; if logged-out visitors see MISS on the home page, something is bypassing it — a query string from an ad campaign, a cookie set by a plugin on every visit, or a page excluded by mistake. A CDN that caches HTML at the edge takes the remaining distance out of the equation for visitors far from your server.
This is where cheap hosting genuinely costs you. An overloaded shared server can take a second just to start PHP on an uncached request. If the cache is working and TTFB is still poor, the host is the bottleneck.
Phase two: let the browser find the hero early, and never lazy-load it
A long resource load delay means the browser learned about the LCP image late. The classic causes are a hero set as a CSS background image, an image injected by a slider's JavaScript, and an image marked loading=lazy. All three hide the image from the browser's preload scanner, which reads the HTML ahead of the parser specifically to start important downloads early.
Use a real img element for the hero wherever you can. Since WordPress 5.5 core adds loading=lazy to images automatically, and since 6.3 it skips the first content images and adds fetchpriority=high to the one it judges most likely to be the LCP. Page builders and themes do not always cooperate with that logic, so inspect the hero's markup: it should have fetchpriority=high and no loading=lazy.
If the hero must be a background image or arrives via script, add a preload link for it in the head, with the same srcset and sizes the visible image uses. That one line often removes most of the delay phase.
Phase three: format, sizing and the srcset WordPress already generates
Load duration is about bytes. WordPress creates several sizes of every uploaded image and writes a srcset so the browser can pick the smallest one that fits, but that only works if the theme outputs images with the core functions and accurate sizes attributes. A theme that hard-codes the full-size URL sends a 2,400-pixel image to a 390-pixel screen.
Serve WebP or AVIF. WordPress supports both formats natively in recent versions, and an image optimisation plugin or CDN can convert existing uploads. For a typical photographic hero, the saving over a JPEG is large enough to show up directly in the load phase.
Then look at the image itself. A hero exported from a design tool at double resolution and 90 per cent quality is often several times heavier than it needs to be. Target the rendered size on the largest common screen, not the size of the original file.
Phase four: render-blocking CSS and fonts
If the image arrives quickly but paints late, something is blocking rendering. Stylesheets in the head block painting until they download and parse, and a typical WordPress page loads several: the theme, the page builder, the block library and a few plugins that enqueue CSS on every page whether it is used or not.
Remove what the page does not use first; dequeueing a contact form plugin's styles on pages without a form is easier and safer than any optimisation trick. After that, inlining the small amount of CSS needed for the first screen and loading the rest without blocking is the standard technique, and most performance plugins offer it — test it carefully, because a bad critical CSS set causes visible layout jumps.
When the LCP element is text, fonts are usually the problem. Self-host the fonts, preload the one weight used above the fold, and set font-display to swap so the heading paints in a fallback font rather than waiting invisibly for the web font.
Measuring the fix in field data, not just Lighthouse
Lighthouse is a single simulated load on a throttled connection. It is excellent for diagnosis and poor as a verdict. Google ranks on field data from real Chrome users, which you see in PageSpeed Insights under the real-user section and in Search Console's Core Web Vitals report.
Field data is a rolling 28-day window, so a fix takes up to four weeks to show fully. Ship the change, confirm it in a lab test, and then watch the field number trend down rather than expecting it to move the next morning. If you want faster feedback, the web-vitals JavaScript library can send real LCP measurements from your own visitors to your analytics.
Frequently asked questions
What counts as the LCP element on a WordPress page?
The largest image, video poster or block of text visible in the viewport when the page loads. On WordPress it is usually the hero image, a slider's first slide or the main heading. It can differ between mobile and desktop, so check the mobile result first.
Why is my LCP worse on mobile than desktop?
Mobile tests use a slower simulated connection and CPU, so every byte and every blocking resource costs more. Phones also often show a different LCP element than desktop. Oversized hero images and render-blocking CSS hurt mobile far more than desktop.
Does lazy loading hurt LCP?
Lazy loading the LCP image does, because the browser waits until layout to start downloading it. Lazy load images below the fold, and make sure the hero has no loading=lazy attribute and ideally fetchpriority=high. Recent WordPress versions do this automatically, but some themes and builders override it.
What is a good LCP score for a WordPress site?
2.5 seconds or less at the 75th percentile of real visits counts as good. Between 2.5 and 4 seconds needs improvement, and anything over 4 seconds is poor. Judge it from field data in PageSpeed Insights or Search Console rather than a single Lighthouse run.
Will a caching plugin fix my LCP on its own?
Only if slow server response is the main problem. Caching shortens time to first byte, but it does nothing for an oversized hero image, a lazy-loaded LCP element or render-blocking CSS. Find which LCP phase is slow before choosing the fix.