To improve LCP in WordPress, first identify the Largest Contentful Paint element on mobile, then reduce server response time with page caching and a CDN, make sure the LCP image is discovered early, not lazy-loaded, sized correctly and served as WebP or AVIF with fetchpriority="high", and remove render-blocking CSS, fonts and scripts before it.
This guide supports my Core Web Vitals guide, which explains the three metrics in general.
How do I find the LCP element?
Run PageSpeed Insights on the URL and open the “Largest Contentful Paint element” diagnostic; it shows the exact element. In Chrome DevTools, record a load in the Performance panel and look for the LCP marker. Check mobile and desktop separately, because the element often differs between layouts.
Common LCP elements on WordPress sites:
- Hero background or slider image.
- The main heading text (when the hero has no image).
- The featured image on blog posts.
- The first product image on product pages.
Understand the four parts of LCP
Google breaks LCP into four sub-parts. Lighthouse and the DevTools performance insights show this breakdown:
- Time to First Byte (TTFB) – how long until the HTML starts arriving.
- Resource load delay – the gap between TTFB and the browser starting to load the LCP image.
- Resource load duration – how long the image takes to download.
- Element render delay – the time after the image loads until it is painted.
Fix the biggest part first. Optimising image size will not help if TTFB is the problem.
Step 1: reduce TTFB
- Page caching. Serve cached HTML instead of running PHP and database queries for every visitor. Use your host’s cache or a well-configured caching plugin.
- Object caching (Redis or Memcached) when the host supports it, especially for WooCommerce and logged-in traffic.
- CDN with HTML caching. Edge caching of HTML helps visitors far from your server. Configure exclusions for cart, checkout and account pages.
- PHP version and resources. A current supported PHP version and enough PHP workers matter on busy sites.
- Slow plugins. Use Query Monitor to find slow queries and external HTTP calls on page load.
Step 2: eliminate resource load delay
The browser should start loading the LCP image as soon as possible.
- Put the hero as a real
<img>in the HTML rather than a CSS background or a slider initialised by JavaScript. - Do not lazy-load it. WordPress adds
loading="lazy"to many images automatically and tries to skip the first content image, but themes and plugins can override this. Check the HTML. - Add
fetchpriority="high":
<img src="/wp-content/uploads/hero-1200.avif"
srcset="/wp-content/uploads/hero-800.avif 800w, /wp-content/uploads/hero-1200.avif 1200w"
sizes="(max-width: 768px) 100vw, 1200px"
width="1200" height="675"
fetchpriority="high" alt="Product showcase" />
- If the image must be a CSS background, preload it:
<link rel="preload" as="image" href="/hero-1200.avif" fetchpriority="high">
Step 3: shorten load duration
- Serve the right size via
srcset; a phone should not download a 2560 px image. - Use AVIF or WebP; see converting images to WebP and AVIF in WordPress.
- Compress sensibly; hero images rarely need maximum quality.
- Serve from a CDN close to visitors.
Step 4: reduce render delay
Even after the image arrives, the browser may wait for:
- Render-blocking CSS. Inline critical CSS and load the rest asynchronously, or remove unused CSS. Many optimisation plugins do this; test the result for visual glitches.
- Web fonts when the LCP element is text. Use
font-display: swap, preload the one or two fonts used above the fold, and consider self-hosting fonts. - JavaScript that hides content until it runs: sliders, animation libraries that start elements at
opacity: 0, A/B testing scripts. If your hero fades in with JavaScript, your LCP waits for that script.
Step 5: get caching headers right
Long cache lifetimes for static assets (CSS, JS, fonts, images) help repeat visits. A frequent conflict: the server sends long Cache-Control headers, but a CDN setting overrides them with a shorter browser TTL. On Cloudflare, the Browser Cache TTL setting can be set to respect existing headers, so your server’s rules apply. Version your asset URLs (for example style.css?ver=1.2.0) so long caching never serves stale files after a release.
Step 6: verify
- Re-run PageSpeed Insights on mobile several times; lab results vary between runs.
- Check the LCP breakdown again to see which sub-part remains largest.
- Wait for field data to update; it is a rolling 28-day window.
WordPress LCP checklist
- LCP element identified on mobile and desktop
- Page cache active and HTML served quickly
- CDN configured, with cart and checkout excluded
- Hero is an
<img>, not lazy-loaded, withfetchpriority="high" - Correct size with
srcsetand modern format - Critical CSS inlined or unused CSS reduced
- Above-the-fold fonts preloaded with
font-display: swap - No JavaScript-dependent fade-in on the LCP element
- Cache headers consistent between server and CDN
Common mistakes
- Heavy sliders as hero sections. A single well-optimised image almost always wins.
- Preloading many images; the priority hint loses meaning.
- Testing logged in, where caching is bypassed.
- Fixing desktop and forgetting the mobile hero is a different image.
Want me to look at your LCP? Send me the URL. If your problem is responsiveness rather than loading, read how to reduce Total Blocking Time.
Frequently asked questions
What is a good LCP score?
A good Largest Contentful Paint is 2.5 seconds or less at the 75th percentile of real page loads. Above 4 seconds is considered poor.
Why is my LCP worse on mobile?
Mobile tests simulate slower CPUs and networks, mobile layouts often use a different LCP element, and large images or heavy scripts hurt more on phones.
Should I preload the hero image?
If the browser discovers the image late, for example as a CSS background, a preload helps. For a normal img tag in the HTML, fetchpriority=high is usually enough.
Does a CDN improve LCP?
A CDN can reduce time to first byte and asset download time for visitors far from your server, especially when it caches HTML as well as static files.


