LCP is not one measurement. It is four, laid end to end, and compressing your hero image only shortens one of them. That is why so many WordPress owners run every image through a compressor, watch the score refuse to move, and conclude that Core Web Vitals are arbitrary. The score was fine. The diagnosis was missing.
Google splits LCP into time to first byte, resource load delay, resource load duration and element render delay. Find out which of the four is eating your budget and the fix follows on its own — and on WordPress specifically, the answer is more often the second one, the part where the browser has not yet worked out that your hero image exists.

LCP is four measurements, not one
Largest Contentful Paint is the time until the biggest content element in the viewport has finished rendering, and it passes at 2.5 seconds or less at the 75th percentile of real page views (web.dev, verified August 2026). Getting there is a relay of four legs, and the total is only ever as good as the slowest one.
The useful part is that web.dev also publishes what the split should look like when a page is in good shape: roughly 40% time to first byte, under 10% resource load delay, roughly 40% resource load duration, under 10% element render delay (verified August 2026). That gives you something better than a pass/fail — it gives you a shape to compare yours against. A page where load delay is a third of the total does not have an image problem. It has a discovery problem.

| Sub-part of LCP | What it measures | Healthy share | What makes it long on WordPress | What fixes it |
|---|---|---|---|---|
| Time to first byte | From the request to the first byte of HTML arriving | ~40% | No page cache, a heavy theme, autoloaded options, an overloaded shared host | Page cache, object cache, a lighter plugin set, a host with real resources |
| Resource load delay | The gap between the HTML arriving and the browser starting to fetch the LCP resource | under 10% | A hero as a CSS background, inside a slider, injected by JavaScript, or marked lazy | Put the hero in the HTML as a real image, preload it, set a high fetch priority |
| Resource load duration | Downloading the LCP resource itself | ~40% | An uncompressed hero, wrong dimensions, no modern format, no CDN | Correct size, WebP or AVIF, a CDN — the part everyone starts with |
| Element render delay | From the resource finishing to the element actually appearing | under 10% | Render-blocking CSS and JS, web fonts, animations that hold content back | Trim render-blocking assets, sort out font loading, drop entrance animations |
Run your page through PageSpeed Insights and read the sub-parts before touching anything. It takes two minutes and it decides which of four unrelated pieces of work you are about to do.
What WordPress already does, and how themes undo it
Compressing the hero is the most common LCP fix and rarely the right one. The problem is usually when the browser finds out about the image, not how heavy it is. This is the WordPress part of the story, and it is more interesting than it sounds, because core has been trying to fix it for you since 2023.
WordPress 6.3 “automatically adds the fetchpriority attribute with a value of ‘high’ to the image it determines most likely to be the ‘LCP image’”, which the Core Performance Team benchmarked as “typically improves LCP by 5-10%” (Make WordPress Core, July 2023, verified August 2026). The same release raised the number of leading images exempt from lazy loading — the wp_omit_loading_attr_threshold filter went from 1 to 3 — so a multi-column layout does not lazy-load something that is on screen immediately, and it guarantees the function “will never return both fetchpriority=“high” and loading=“lazy” for the same image”.
Then comes the sentence that explains most broken WordPress LCP in the field: the function “will never override attributes that are already provided, so if you set a fetchpriority or loading attribute on an image before this function is called, the attribute will be kept as is”. A theme, a page builder or an optimisation plugin that stamps loading=“lazy” onto every image gets there first, and core politely stands aside. Which puts you exactly where web.dev says not to be: “Never lazy-load your LCP image, as that will always lead to unnecessary resource load delay, and will have a negative impact on LCP” (verified August 2026).
The other half of the problem is that core is making a guess from the markup, and plenty of WordPress heroes are invisible to it.

| How your hero is delivered | Can the browser find it early? | What that does to LCP | What to do |
|---|---|---|---|
| A normal image in the content or the featured image | Yes, it is in the HTML | Best case; core can apply its high fetch priority | Leave it alone and check nothing has overridden the attributes |
| A CSS background image | No — the stylesheet has to load and be parsed first | Load delay grows by however long the CSS took | Use a real image element, or preload the file explicitly |
| A slider or carousel | Rarely — the first slide is often built by JavaScript | The largest element appears after a script runs | Render the first slide server-side, or drop the slider |
Marked loading=“lazy” by a theme or plugin | Found, then deliberately deferred | Directly the worst case; core will not override it | Exclude above-the-fold images from lazy loading in the plugin’s settings |
| Injected after load by JavaScript | No, not until the script has run | Load delay plus render delay, stacked | Put it in the initial HTML; scripts should not own your hero |
| There is no hero — the LCP element is text | Not applicable | Time goes into server response and font loading instead | Work on TTFB and web fonts; there is no image to optimise |
What to do, in order
- Find out what your LCP element actually is. PageSpeed Insights names it. People are wrong about this surprisingly often — it is a logo, a background, a paragraph of text, not the photo they assumed.
- Read the four sub-parts and compare the shape against roughly 40 / under 10 / 40 / under 10. The outlier is your job for today.
- Check the attributes on the LCP image in the page source. If it carries
loading=“lazy”, find what put it there and stop it. If it has nofetchpriority=“high”, work out why core did not add it. - Get the hero into the HTML. Out of the CSS background, out of the slider, out of a script. This is the single biggest lever on most WordPress sites and it costs nothing in image quality.
- Then do the image itself — right dimensions for the breakpoint, WebP or AVIF, and a CDN if your audience is not next door to your server.
- Then TTFB, if that is where the weight is: page cache, object cache, a look at what is autoloading on every request — and be aware that three of TTFB’s five phases finish before your server is even asked for the page.
- Measure in the field, not on your laptop. Give Search Console four weeks and check whether real visitors moved, split by mobile and desktop.
That last step is worth insisting on. The people who own a site are the worst-placed people to judge its speed: fast connection, warm cache, the same pages every day. It got slower one plugin at a time and they stopped noticing months ago. The visitor on a mid-range phone on mobile data never had a warm cache, and left before the hero painted. Only field data has both of them in it.
When it is not worth chasing
If you already pass LCP in the field, stop. Going from 2.1s to 1.6s changes no classification, and Core Web Vitals are a ranking signal of modest weight, not a leaderboard. The time is better spent on whichever vital you are failing, or on the page itself. A fast page nobody wants to read is still a page nobody wants to read.
And do not fix LCP by deleting the hero. It comes up more than it should: the fastest image is no image, so someone removes the photograph that was doing the selling and celebrates a green score. The metric exists as a proxy for how quickly the visitor sees something worth staying for. Removing the something is not a win.
Where it does pay: a site that fails LCP in Search Console on mobile, or one where the hero sits inside a slider and nobody has ever checked what that costs. That is what our WordPress speed optimisation work covers, starting from the sub-part breakdown rather than a generic checklist. On a shop the same logic applies to the catalogue, with the extra complication that buyers are served the uncached version of the store, and that checkout is measured by INP rather than LCP. The sister metric to this one is layout stability, where the lab test has the opposite problem — Lighthouse reports a CLS of 0 on pages that shift constantly.
Frequently asked questions
What is a good LCP score?
Largest Contentful Paint should happen within 2.5 seconds of the page starting to load, measured at the 75th percentile of page views and split between mobile and desktop (web.dev, verified August 2026). The percentile matters more than the number: it means a quarter of your visitors can be slower than that and you still pass, and it means one fast test on your own laptop proves nothing.
I compressed my images and LCP did not change. Why?
Because compression only shortens one of the four parts LCP is made of — the time spent downloading the resource. If your problem is that the browser does not discover the image until late, or that the server takes a second to send the HTML, a smaller file changes almost nothing. Break the metric down before optimising it, otherwise you are guessing which quarter to work on.
Should I lazy-load my hero image?
No. web.dev is unambiguous about it: never lazy-load your LCP image, because it always adds unnecessary resource load delay and hurts LCP. WordPress already knows this — since 6.3 it will not return both a high fetch priority and lazy loading for the same image. The trouble starts when a theme or an optimisation plugin adds the lazy attribute first, because core does not override what is already there.
Does WordPress optimise LCP on its own?
Partly, since version 6.3. It adds fetchpriority="high" to the image it judges most likely to be the LCP element, which the Core Performance Team measured as typically improving LCP by 5-10%, and it skips lazy loading on the first images in the content. It is a guess based on the markup, so it works when the hero is a normal image in the content and misses when the hero is a CSS background, a slider, or output by a page builder.
Is my LCP element always an image?
No. It is whatever the largest content element in the viewport turns out to be, which on a text-led page is often a heading or a block of paragraph text. That case is worth recognising because the fix is completely different: with a text LCP there is no image to optimise, so the time is going into server response and web fonts instead.
Do I use PageSpeed Insights or Search Console?
Both, for different jobs. Search Console reports field data from real Chrome users, which is what counts as passing or failing. PageSpeed Insights shows you that field data at the top and a lab test underneath, and the lab test is where you get the sub-part breakdown that tells you what to fix. Diagnose in the lab, judge in the field.
Sources (verified August 2026): web.dev — Optimize Largest Contentful Paint; web.dev — Web Vitals; Make WordPress Core — Image performance enhancements in WordPress 6.3.