Images are usually the single heaviest part of a WordPress page, and very often the page’s Largest Contentful Paint (LCP) element as well. Getting image handling right, dimensions, formats, compression, and loading behavior, tends to produce the largest single improvement available on most content-driven WordPress sites. This guide covers the full picture, including how the LCP image specifically should be treated differently from every other image on the page.
Image dimensions: serving the right size, not just a smaller file
The most common image mistake is not file compression, it’s serving an image far larger than the space it’s displayed in. A 3,000-pixel-wide photograph displayed in a 700-pixel-wide content column wastes bandwidth regardless of how well it’s compressed. Before compression settings matter at all, confirm that the image’s actual pixel dimensions are reasonably close to its largest rendered display size (accounting for high-density “retina” screens, which may reasonably request roughly double the display size).
Always set explicit width and height attributes on images. This allows the browser to reserve the correct space in the layout before the image downloads, which prevents layout shifts (a factor in Cumulative Layout Shift) and, as covered below, is also required for WordPress’s native lazy-loading behavior to apply.
Responsive images: srcset and sizes
Since WordPress 4.4, core has automatically generated a srcset attribute (a list of available image sizes) and a sizes attribute (a hint about how wide the image will render at different viewport widths) for images inserted through the media library. This allows the browser to select the most appropriate file size for the visitor’s specific device and viewport, rather than downloading a single fixed size for every visitor. This works out of the box, but the default sizes value WordPress generates is a general-purpose estimate; on complex layouts (multi-column grids, sidebars, or page-builder layouts) it can be worth refining manually, since an inaccurate sizes value can cause the browser to select a larger file than actually needed. Inspecting the “Network” panel in browser developer tools will show exactly which file size was requested for a given image, which is the most reliable way to confirm the attribute is doing its job.
Compression
Compression reduces file size for a given set of pixel dimensions, and is a separate concern from choosing the correct dimensions in the first place. Most image compression falls into two categories: lossless (reduces file size with no quality loss, typically modest savings) and lossy (reduces file size more substantially by discarding some image data, with quality loss that is usually imperceptible at reasonable settings). For photographic content, a moderate lossy compression setting is generally the most effective balance between file size and visible quality; verify results visually rather than assuming a single compression percentage is universally correct for every image, since it depends heavily on image content and how it is displayed.
WebP and AVIF considerations
Beyond dimensions and compression settings, the image file format itself affects final file size. WordPress has supported uploading and using WebP images natively since WordPress 5.8, and AVIF since WordPress 6.5, provided the hosting server’s image processing library (typically Imagick or GD) supports the format in question; not every hosting environment does, so this is worth confirming before relying on it. Both formats generally produce smaller files than equivalent-quality JPEG or PNG images, with AVIF often achieving smaller file sizes still, though encoding time and library support are less universal than WebP’s at this point.
It’s worth being precise about what “support” means here: WordPress being able to upload and display a format is a different capability from WordPress automatically batch-converting an entire existing media library, or automatically serving different formats to different browsers via a <picture> element fallback chain. Those additional capabilities typically require a dedicated image-optimization plugin or a compatible image CDN, rather than being automatic behavior of WordPress core alone.
Lazy loading, and why the LCP image is the exception
Since WordPress 5.5, WordPress automatically adds the native loading="lazy" attribute to images that have both width and height attributes present, deferring their download until the browser determines they are likely to be needed soon (typically as the visitor scrolls toward them). This is genuinely useful for images further down a page, since it avoids downloading content most visitors may never scroll to see.
However, lazy-loading the image that turns out to be the page’s LCP element is directly counterproductive: it delays the exact resource the browser needs to paint as quickly as possible, working against the very metric being optimized. WordPress core has addressed part of this directly: since WordPress 6.3, core attempts to detect which image is likely to be the LCP element (generally the featured image or first content image above a size threshold) and both omits the lazy-loading attribute and adds fetchpriority="high" to that image automatically. This heuristic is not perfect for every theme or page-builder layout, so it’s worth manually verifying, using the methods described later in this article, that your actual LCP image is not being lazy-loaded.
Above-the-fold images and fetch priority
Images likely to be visible without scrolling should generally not be lazy-loaded. However, fetchpriority="high" should be reserved for the page’s single most important image—usually the actual LCP image—rather than added to every above-the-fold image. Marking several images as high priority makes the hint less useful because those resources still compete with one another. Priority hints work alongside, rather than instead of, correct dimensions and reasonable file size; a correctly prioritized image that is still needlessly oversized will still be slow.
Preloading the LCP image
For further control, a <link rel="preload"> tag added to the document head can instruct the browser to begin fetching the LCP image immediately, before the browser’s HTML parser would otherwise discover it, which is particularly useful when the image is only discoverable after CSS or JavaScript execution (for example, a background image set via CSS, or an image inserted by a page-builder script). Preloading and fetchpriority="high" are complementary, not redundant: preload affects when the browser starts the request, while fetchpriority affects how the request is prioritized relative to other simultaneous requests. Preloading should be used selectively, since preloading too many resources competes for the same limited bandwidth and can slow down other important resources.
Background images
Images set via CSS background-image are not discovered by the browser’s HTML parser the way an <img> tag is; they are only discovered once the relevant CSS has been downloaded and parsed, which is a meaningfully later point in the loading process. If a CSS background image is the visual element most likely to be the page’s LCP element (a common pattern in hero sections and page-builder headers), it is often worth converting it to a genuine <img> element where the design allows, or explicitly preloading it, since a background image cannot receive the loading or fetchpriority attributes that apply to standard image tags.
Image CDN considerations
An image-specific CDN (either a general CDN with image-optimization features, or a dedicated image CDN service) can automate much of the above: generating multiple sizes, converting to modern formats, applying compression, and serving from edge locations closer to visitors. This can meaningfully reduce ongoing manual work, particularly for sites with large media libraries or frequent publishing. The tradeoff is an additional dependency and, in some configurations, an additional DNS lookup or connection setup; whether this is worthwhile depends on site size, publishing volume, and existing hosting/CDN setup rather than being a universal recommendation for every site.
Common mistakes
- Uploading and inserting an image at its full original resolution rather than an appropriately sized version
- Missing
width/heightattributes, which both harms layout stability and can prevent native lazy loading from applying correctly - Lazy-loading the LCP image, delaying the very content the metric measures
- Relying on a CSS background image for a large hero visual without preloading it or considering a standard image tag instead
- Assuming a compression percentage that works well for one photo will work identically well for every image on the site
- Enabling WebP or AVIF uploads without confirming the hosting server’s image library actually supports encoding that format
- Adding preload tags for many images “just in case,” which competes with other critical resources rather than helping
Testing your image and LCP setup
PageSpeed Insights and Chrome DevTools both identify the specific element responsible for a page’s LCP measurement; in DevTools, the Performance panel’s LCP entry can be expanded to highlight the exact element on the page. Confirm that this element, if it is an image, is not carrying loading="lazy", and check the Network panel to confirm the file size actually downloaded is reasonably close to its rendered display size rather than several times larger. As covered in How to Measure WordPress Speed Before Making Any Changes, always test as a logged-out visitor and record results before and after any change, since a single test run can vary and a documented baseline is what makes the comparison meaningful. A deeper breakdown of how to diagnose LCP specifically, including server-side causes unrelated to images, is covered in Largest Contentful Paint in WordPress: How to Find and Fix It.
Practical checklist
- Confirm images are uploaded and inserted close to their actual maximum display size, not their original camera or export resolution
- Verify
widthandheightattributes are present on all images - Confirm the
srcset/sizesoutput matches what the layout actually needs, especially on complex or multi-column templates - Apply reasonable lossy compression to photographic images and verify visually
- Use WebP or AVIF where your hosting environment supports encoding them
- Identify your actual LCP element using PageSpeed Insights or DevTools, and confirm it is not lazy-loaded
- Consider preloading the LCP image if it is discovered late (for example, via CSS or JavaScript)
- Review any CSS background images used as large hero visuals and consider converting critical ones to standard image tags
Key Takeaways
- Serving an image at the correct pixel dimensions matters more than compression settings alone, and both should be addressed.
- WordPress natively supports responsive images (since 4.4), lazy loading (since 5.5), WebP (since 5.8), AVIF (since 6.5), and automatic LCP-image detection with fetch priority (since 6.3), but each has caveats worth verifying.
- The LCP image should never be lazy-loaded, and should generally receive
fetchpriority="high"and, where needed, a preload hint. - CSS background images are discovered later than standard
<img>tags and need special handling if they serve as a page’s primary visual. - Always verify actual behavior with PageSpeed Insights or DevTools rather than assuming a setting is working as intended.
FAQs
Does WordPress automatically know which image is my LCP element?
Since WordPress 6.3, core attempts to detect the likely LCP image automatically and adjusts its loading behavior accordingly. This heuristic works well in many cases but is not guaranteed to be correct on every theme or page-builder layout, so it’s worth manually verifying with PageSpeed Insights or DevTools.
Should I convert my entire media library to WebP or AVIF?
It can help, but confirm your hosting server supports encoding the format first, and be aware that WordPress does not automatically batch-convert existing uploads; that typically requires a dedicated plugin or service.
Is preloading always a good idea for my LCP image?
Not automatically. Preloading is most useful when the image is discovered late by the browser, such as through CSS or JavaScript. Preloading resources unnecessarily competes with other important resources for bandwidth and priority.
Why is my hero image still slow even though it’s compressed well?
Compression only addresses file size at a given resolution; check whether the image is being lazy-loaded, whether it’s a CSS background image discovered late in the page load, or whether it’s simply larger in pixel dimensions than needed for its display size.
Do I need an image CDN if I already use a general-purpose CDN?
Not necessarily. Some general CDNs include image-specific optimization features already. Check what your current CDN supports before adding a separate, dedicated image CDN service.
Sources and further reading
- WordPress Developer Resources — Responsive Images (Common APIs Handbook)
- Make WordPress Core — Lazy-loading images in 5.5; Image performance enhancements in WordPress 6.3; WordPress 5.8 adds WebP support
- Google web.dev — Optimize Largest Contentful Paint
- Chrome for Developers — LCP breakdown (Performance insights)