Optimize Critical Images
Eagerly load and prioritise the LCP image while lazy-loading everything below the fold.
Metrics
This technique can move up to 100% of LCP's share of the Lighthouse score.
This technique does not move TBT.
This technique does not move CLS.
This technique can move up to 100% of FCP's share of the Lighthouse score.
This technique can move up to 67% of SI's share of the Lighthouse score.
This technique does not move TTFB.
Each ring is a metric this technique moves.
Impact grade, A+ to D: how much of the Lighthouse score this technique can move. Unaffected: TBT, CLS, TTFB.
The Problem
Browsers often discover the LCP image late — buried in CSS, revealed by JavaScript, or treated as equal priority to dozens of other images. When the browser does not know an image is critical it may assign it a lower network priority, start its download after less important requests, or have it compete with below-the-fold images for bandwidth. The result is a slow LCP even when the image itself is well-compressed.
Performance Impact
LCP
High
browser prioritises the LCP image download above all other images
FCP
Medium
preloading ensures the browser discovers the image in the HTML head, not after CSS/JS parse
SI
hero and LCP images paint sooner; visible viewport slots fill faster, pulling the speed index curve forward
How it works
01
Identify the LCP image
Use PageSpeed Insights, Chrome DevTools Performance panel, or WebPageTest to confirm which image element is the LCP candidate for each key page template. The LCP element can differ between mobile and desktop viewports.
02
Preload the LCP image from the HTML head
A
<link rel="preload" as="image">tag in<head>instructs the browser to start downloading the image before it parses the rest of the HTML, before it evaluates CSS or executes scripts. This is the most powerful early-discovery technique.03
Set fetchpriority="high" on the img tag
fetchpriority="high"tells the browser this image should outrank other competing requests in the network priority queue. WordPress 6.3+ attempts to apply this automatically to likely LCP images; manual addition is still more reliable for specific templates.04
Lazy-load everything else
Every non-critical image should carry
loading="lazy". This keeps the bandwidth budget free for the LCP image and above-the-fold rendering. The combination of a high-priority LCP image and deferred everything-else is more effective than either technique alone.
Preload in wp_head
<?php
function preload_lcp_image() {
if ( is_front_page() ) {
$lcp_url = get_theme_mod('hero_image_url');
if ( $lcp_url ) {
printf(
'<link rel="preload" as="image" href="%s" fetchpriority="high">\n',
esc_url( $lcp_url )
);
}
}
}
add_action( 'wp_head', 'preload_lcp_image', 1 );Add the preload as early as possible — use priority 1 on wp_head so it appears before stylesheets and scripts.
fetchpriority on the img tag
<!-- LCP hero image — load eagerly with high priority -->
<img src="hero.jpg"
alt="Hero image"
width="1200"
height="600"
fetchpriority="high">
<!-- Below-fold images — defer -->
<img src="product.jpg"
alt="Product"
width="800"
height="600"
loading="lazy">Limitations
- Preloading any image that is not actually the LCP wastes a high-priority network slot. Always verify the LCP element with tooling — do not guess based on visual inspection alone.
- The LCP element can differ by viewport size. A desktop hero image may not be the LCP on mobile if it is hidden with CSS. Check both.
fetchpriorityis a hint, not a command. The browser may still adjust priorities based on network conditions and its own heuristics.- Preloading helps with download timing, but a slow server (high TTFB) limits how much preloading can help. Fix TTFB first if it is above 600ms.
Common Mistakes
Preloading multiple images or non-LCP images
Preload only the single confirmed LCP image. Each preload consumes a high-priority network slot that could otherwise accelerate other critical resources.
Adding fetchpriority=”high” and loading=”lazy” to the same image
These attributes conflict. The LCP image should never be lazy-loaded. Remove loading="lazy" from any image that also carries fetchpriority="high".
Assuming WordPress auto-applies fetchpriority correctly
WP Core’s automatic detection works for standard post thumbnails but may miss hero images set via theme mods, ACF fields, or custom templates. Verify with PageSpeed Insights after relying on it.
Skipping basic image optimisation and relying on priority alone
A 2MB hero image with high priority still takes several seconds on a slow connection. Compress, resize to display dimensions, and serve in WebP or AVIF before tuning fetch priority.
Need help applying this to your site?
Targeted fixes, not guesswork. We identify which techniques move the needle for your specific WordPress stack.
Start an Engagement