A slow largest contentful paint (LCP) usually comes down to one element, most often the hero image, reaching the screen late. The fix depends on which of four parts of the load is taking the time, so measure before you change anything.
Our Core Web Vitals explainer covers what LCP is and the 2.5-second target. This piece goes one level down: how to find the LCP element, how to read its four parts, the fix for each part, and the settings that matter on WordPress and Drupal.
The short version: find the element in PageSpeed Insights or Chrome DevTools, then see where the time goes. On slow sites, most of it is usually server response and the wait before the image request starts, not the download. Cache pages, put the hero image in the HTML, give it fetchpriority="high", never lazy-load it, and only then work on image size and format.
The four parts of largest contentful paint
web.dev’s guide to optimizing LCP splits every LCP time into four parts that add up to the total.
| Part | What it measures | Rough share on a fast page | Usual cause on CMS sites |
|---|---|---|---|
| Time to First Byte (TTFB) | Until the first byte of HTML arrives | About 40% | No page cache, slow hosting, redirects |
| Resource load delay | From TTFB until the image starts downloading | Under 10% | Lazy-loaded hero, image set in CSS or JavaScript |
| Resource load duration | The image download itself | About 40% | Oversized or uncompressed image |
| Element render delay | From download finished until the element shows | Under 10% | Blocking CSS and scripts, fonts, sliders |
web.dev calls those shares guidelines, not rules. If the LCP element is text, there is no download, so the time sits in TTFB and render delay.
A 2024 web.dev analysis of Chrome field data, "Common misconceptions about how to optimize LCP", shows why order matters. For the median origin with poor LCP, the 75th percentile times were 2,270 ms for TTFB, 1,290 ms for load delay, 350 ms for load duration and 360 ms for render delay. The article says image download time is "almost never the bottleneck." Compression helps, but rarely fixes a failing page alone.
How to find the largest contentful paint element
Start with a URL that fails in Search Console, and test on mobile first.
PageSpeed Insights. The top section shows field data from real Chrome users. Below it, the Lighthouse run has a "Largest Contentful Paint element" diagnostic that names the element and breaks its time into the four parts. The field number tells you whether there is a problem. The breakdown tells you where to look.
Chrome DevTools. Record a page load in the Performance panel. The "LCP breakdown" insight splits the time into the four parts. "LCP request discovery" checks that the image is in the HTML, has high fetch priority and is not lazy-loaded. Chrome’s Performance Insights documentation says both insights appear in DevTools and Lighthouse.
CrUX by part. The CrUX API and CrUX History API report the four parts from real visits, according to the Chrome team’s February 2025 release note. That needs enough traffic for your site to be in CrUX.
Three details trip people up:
- The element can differ between mobile and desktop. Check both.
- Chrome skips elements with zero opacity, full-viewport backgrounds and low-detail placeholders, per web.dev’s LCP definition.
- Reporting stops when the visitor taps, scrolls or presses a key.
Fix slow TTFB first
If the HTML takes two seconds to arrive, no front-end fix gets largest contentful paint to 2.5 seconds. web.dev’s TTFB article suggests 0.8 seconds or less as a rough guide.
- Serve cached pages to anonymous visitors. A page built fresh on every request is a common cause of slow TTFB.
- Put a CDN in front. Our explainer on what a CDN is covers how edge caching cuts network time.
- Remove redirects. Missing https and inconsistent trailing slashes are common causes.
- Check the host. Our managed WordPress hosting framework covers what to look for.
web.dev’s TTFB guidance warns that caching "can mask a slow backend." Member pages, search results and the first visit after a purge still hit the origin. Test with a URL parameter that bypasses the cache to see the real server time. If your host changes its edge layer, recheck, as we noted when Pantheon made its Global CDN the default.
Fix resource load delay: let the browser find the hero early
Load delay is the gap between the HTML arriving and the image request starting. Three things cause it.
Lazy loading on the hero. The optimize-LCP guide says: "Never lazy-load your LCP image, as that will always lead to unnecessary resource load delay."
An image hidden from the HTML. A hero set as a CSS background, or added by JavaScript, is found late. Use a plain <img> tag where you can. If you cannot, add a preload in the head. web.dev’s Fetch Priority article says preload "is still required for early discovery of LCP images included as CSS backgrounds."
Normal priority. Add fetchpriority="high" to the LCP image, and to no more than one or two images per page. If you preload the image, put the attribute on the preload too. In a Google Flights test described in that article, fetch priority on the hero cut LCP from 2.6 to 1.9 seconds.
Fix load duration: image size and format
Once the request starts early, make the file small.
- Serve the right size. A 4,000-pixel upload shown at 800 pixels wastes most of its bytes. Make sure the theme serves resized versions through
srcset. - Use AVIF or WebP. The optimize-LCP guide names both. WordPress’s AVIF dev note says AVIF images “can be up to 50% smaller than JPEGs” at the same quality.
- Compress. Hero images rarely need maximum quality.
web.dev adds a caution. If something else blocks rendering, a smaller image can just move the wait into render delay, and largest contentful paint stays the same.
Fix render delay: CSS, fonts and scripts
Render delay is time after the download but before the element shows. The optimize-LCP guide lists the causes:
- Render-blocking stylesheets. Remove unused CSS, defer non-critical CSS and minify. Inline only small stylesheets.
- Synchronous scripts in the head. Use
deferorasync, or move them. - Web fonts. When a headline is the element, use a
font-displayvalue other thanautoorblockso text shows in a fallback font first. - Hidden content. A/B testing tools that hide the page until their script runs delay everything.
- Long tasks. A busy main thread holds up rendering. Our guide to fixing INP covers breaking them up.
On many association and university sites, third-party tags in the head often add much of the render delay. Audit the tag manager before rewriting theme CSS.
Sliders and carousels
A hero slider can hurt three of the four parts. It adds JavaScript, often sets slides as CSS backgrounds and can load every slide at the same priority.
If the slider stays, the Fetch Priority article recommends fetchpriority="high" on the first visible slide and fetchpriority="low" on hidden ones. Make the first slide a real <img> in the HTML that shows before the slider script runs. The simpler fix is one static hero image.
Largest contentful paint on WordPress
WordPress core handles part of this, as long as images go through core functions. According to the WordPress 6.3 image performance dev note:
- Core adds
fetchpriority="high"to the first large image in the response. “Large” means at least 50,000 pixels (width times height), adjustable with thewp_min_priority_img_pixelsfilter. - Core skips
loading="lazy"on the first images it expects in view. Version 6.3 raised that default count from 1 to 3. - Core does not override attributes you set yourself.
- Custom theme markup that bypasses core functions needs a call to
wp_get_loading_optimization_attributes()to get these attributes.
That last point is where most WordPress problems live. Page builders, slider plugins and custom hero blocks often write their own image markup. Check the element in PageSpeed Insights and confirm it has high priority and no lazy loading. Also check for a performance plugin that lazy-loads every image.
The WordPress 6.5 AVIF dev note says sites can upload AVIF if the server’s image library supports it (Tools, then Site Health, then Info, then Media Handling). Core does not convert JPEG uploads to AVIF by default. The image_editor_output_format filter or a plugin does that.
Largest contentful paint on Drupal
Drupal lazy-loads images by default, which is the main thing to undo for the hero. A Drupal 9.1 change record added loading="lazy" and made the image formatter configurable as lazy or eager. Since Drupal 10.1, the responsive image formatter has the same setting, and new fields default to lazy.
- Set the hero field to eager in the display settings of the view mode that renders it. Check Views and Layout Builder blocks that render it separately.
- Add fetch priority yourself. A contributed module’s page says core “lacks easy controls for advanced performance attributes.” A Twig template override or that kind of module fills the gap.
- Use AVIF where the server supports it. Drupal 11.2 added a Convert to AVIF image effect with a fallback style, such as WebP. Existing sites may keep their old image styles, so check them.
- Keep caching on. Personalized blocks, such as member greetings from an AMS, can make a page uncacheable.
Dated facts, as of October 2026
These version details were checked in October 2026.
| Item | Status as of October 2026 | Source |
|---|---|---|
| fetchpriority support | Chrome and Edge 102, Firefox 132, Safari 17.2 | web.dev Fetch Priority article |
| WordPress | Auto fetchpriority since 6.3; AVIF uploads since 6.5 | make.wordpress.org dev notes |
| Drupal | Lazy by default since 9.1; AVIF effect in 11.2 | drupal.org change records |
| CrUX LCP parts | In the CrUX API and History API since February 2025 | Chrome CrUX release note |
Frequently Asked Questions
What is a good largest contentful paint time?
2.5 seconds or less at the 75th percentile of real page loads, on mobile and desktop separately. Over 4 seconds is poor.
How do I find the LCP element?
Use the “Largest Contentful Paint element” diagnostic in PageSpeed Insights, or record a load in the DevTools Performance panel and open the LCP breakdown insight.
Which part of LCP should I fix first?
Whichever the breakdown shows is largest. On most slow sites that is TTFB or load delay, so caching and early discovery of the hero come before compression.
Should the hero image ever be lazy-loaded?
No. Lazy loading makes the browser wait to fetch the one image that most needs to load early.
Should I preload the LCP image?
Only when the browser cannot find it in the HTML, such as a CSS background. Add fetchpriority=”high” to the preload as well.
Will AVIF or WebP fix a slow largest contentful paint?
They shrink the download, which is rarely the largest part. If the server is slow or the image is found late, a smaller file alone will not move it much.
Why does WordPress not prioritize my hero image?
Core only adds these attributes to images it renders through its own functions. Page builders, sliders and custom theme markup often bypass them.
How do I stop Drupal lazy-loading the hero image?
Set the image or responsive image formatter for that field to eager in the view mode that renders the hero.
How long until a fix shows in Search Console?
The report uses the last 28 days of field data, so expect about four weeks. Lab tools show the change right away.