WordPress Speed

How to Optimise WordPress Images for Speed (Complete Guide)

Images are the #1 cause of slow WordPress sites. Here's how to compress, convert, lazy load, and deliver them properly for maximum speed.

Jamie McKaye
Jamie McKaye
11 min read
How to Optimise WordPress Images for Speed (Complete Guide)
Key Takeaways
  • Images account for 50–70% of total page weight on the average WordPress site — they’re the single biggest payload contributor and the easiest to fix
  • WebP reduces image file sizes by 25–35% compared to JPEG at equivalent quality — and it’s supported by 97%+ of browsers in 2026
  • Never lazy load the LCP (Largest Contentful Paint) image — your hero image should load eagerly with fetchpriority="high" for the fastest possible render
  • Explicit width and height attributes prevent Cumulative Layout Shift (CLS) — a Core Web Vitals metric that directly impacts search rankings
  • Responsive images with srcset serve appropriately sized files to each device — a 400px-wide mobile screen shouldn’t download a 2000px-wide desktop image

The Impact of Images on WordPress Performance

On the average WordPress site, images account for 50–70% of total page weight. A typical blog post might load 500KB of HTML, CSS, and JavaScript — and 2MB of images. An ecommerce product page with a gallery can easily reach 5MB+ of image data.

Every kilobyte of image data must be downloaded by the visitor’s browser before the image appears on screen. On a 4G mobile connection (the global average), downloading 2MB of images takes 4–6 seconds. That’s 4–6 seconds of blank image placeholders, loading spinners, or layout shifts as images pop in one by one.

The business impact is direct: images are frequently the Largest Contentful Paint (LCP) element. Your hero image, product photo, or featured blog image is likely the largest visible element in the initial viewport. If that image is unoptimised — too large, wrong format, not properly loaded — your LCP score suffers, your Core Web Vitals fail, and Google penalises your rankings accordingly. Unoptimised images are one of the top causes of slow WordPress sites.

The good news: image optimisation is the single highest-ROI performance task in our WordPress speed optimisation process. The techniques are straightforward, the tools are mostly automated, and the results are immediate and dramatic. A site loading 3MB of images can typically be reduced to 400–600KB with zero visible quality loss.

Choosing the Right Format: WebP vs AVIF vs JPEG vs PNG

JPEG: The legacy standard for photographs. Good compression, universal support, but no transparency and no animation. Quality degrades noticeably below 70% compression. Still acceptable in 2026 but there’s no reason to choose JPEG over WebP for new images.

Image format comparison showing JPEG as the largest file in red, WebP smaller in amber, and AVIF smallest in green — all at equivalent visual quality
Same visual quality, dramatically different file sizes. WebP is 25-35% smaller than JPEG. AVIF pushes that to 50% — but browser support is still catching up.

PNG: Lossless compression, supports transparency. Essential for logos, icons, and graphics with sharp edges or text. File sizes are significantly larger than JPEG/WebP for photographic content. Never use PNG for photographs — a 2000px photo that’s 200KB as JPEG can be 2MB+ as PNG.

WebP: Google’s modern format, supported by 97%+ of browsers. Provides 25–35% smaller files than JPEG at equivalent visual quality. Supports both lossy and lossless compression, transparency, and animation. WebP is the standard recommendation for WordPress in 2026 — it’s the best balance of compression, quality, and browser compatibility.

AVIF: The newest format, based on the AV1 video codec. Provides 40–50% smaller files than JPEG — significantly better compression than WebP. Browser support is at approximately 92% (all modern browsers except older Safari versions). AVIF encoding is slower than WebP, which can impact server-side conversion performance. WordPress 6.5+ supports AVIF uploads natively.

Our recommendation: Use WebP as your primary format today. It’s supported everywhere that matters, the quality is excellent, and every WordPress image optimisation tool supports it. Consider AVIF for sites where you control the audience (modern browser visitors) and want maximum compression. Always provide a JPEG/PNG fallback for the 3–8% of visitors on browsers that don’t support WebP/AVIF — WordPress’s <picture> element handling or plugin-based format switching handles this automatically.

Compression: Finding the Quality Sweet Spot

Lossy vs lossless: Lossy compression discards image data to reduce file size — some visual quality is lost, but at reasonable settings (quality 75–85) the difference is imperceptible. Lossless compression preserves all image data — no quality loss, but smaller file size reductions (typically 10–30%). For photographs, lossy compression at quality 80 is the sweet spot — invisible quality reduction with 60–80% file size savings.

Quality settings: Most tools use a 1–100 quality scale. Quality 100 means no compression. Quality 1 means maximum compression with severe quality loss. The practical range for web images is 70–85. Below 70, compression artefacts become visible (banding in gradients, blurring of fine details). Above 85, the file size increases significantly with negligible quality improvement.

WordPress image optimisation plugins:

ShortPixel: Our preferred tool. Offers lossy, glossy (visually lossless), and lossless compression. Bulk optimises existing media. WebP and AVIF conversion included. Free tier: 100 images/month. Paid: from $4.99 for 5,000 credits. The “glossy” setting provides the best quality-to-size ratio — it’s lossy compression with additional quality preservation algorithms that maintain sharpness.

Imagify: Made by the WP Rocket team. Three compression levels (normal, aggressive, ultra). WebP conversion included. Free tier: 20MB/month. Integrates seamlessly with WP Rocket. The “aggressive” setting is comparable to ShortPixel’s “glossy” — good balance of size and quality.

Smush (WPMU DEV): Free tier has no monthly limit but caps at 5MB per image and doesn’t include WebP conversion (Pro required). The free version is adequate for basic compression but lacks the advanced features of ShortPixel and Imagify. Pro version ($7.50/month) adds WebP, CDN, and lazy loading.

Responsive Images: The srcset Attribute

When you upload an image to WordPress, the platform automatically generates multiple sizes (thumbnail, medium, large, full). WordPress also generates srcset and sizes attributes on <img> tags, which tell the browser to download the appropriately sized version for the visitor’s screen.

Without srcset, a mobile visitor on a 400px-wide screen downloads the same 2000px-wide image as a desktop visitor on a 1920px monitor. That’s 5x more pixels than the mobile screen can display — wasted bandwidth and slower load times.

With srcset, the browser selects the closest size match. A 400px mobile screen downloads the 480px-wide version (typically 40–60KB instead of 200–400KB). The visitor sees identical visual quality because their screen can’t display the extra pixels anyway.

Verifying srcset works: Inspect any image on your site in Chrome DevTools. Check the <img> tag for srcset and sizes attributes. If these are missing, your theme may be using hardcoded <img> tags instead of wp_get_attachment_image() or the_post_thumbnail() — the WordPress functions that automatically include responsive attributes.

Custom sizes: If your theme uses non-standard image sizes (like a 16:9 hero banner), register them in your theme’s functions.php with add_image_size(). WordPress will generate these sizes on upload and include them in srcset. After adding new sizes, regenerate thumbnails for existing images using WP-CLI: wp media regenerate --yes.

Explicit Width and Height: Preventing Layout Shift

Cumulative Layout Shift (CLS) measures how much page content moves around as the page loads. Images without explicit width and height attributes are one of the most common causes of poor CLS scores.

The problem: When the browser encounters an <img> tag without dimensions, it doesn’t know how much space to reserve for the image. It renders the surrounding content with zero space for the image. When the image finally loads, the browser recalculates the layout and pushes everything below the image downward. This “jump” is layout shift — it’s jarring for users and penalised by Google.

The fix: Always include width and height attributes on every <img> tag. The browser uses these to calculate the aspect ratio and reserve the correct space before the image loads. Add CSS height: auto; and max-width: 100%; to ensure images remain responsive while respecting the reserved aspect ratio.

WordPress automatically adds width and height to images inserted via the editor. But custom theme code, page builder output, and manually coded HTML often omit them. Audit your templates and add dimensions to any <img> tag that’s missing them. The PageSpeed Insights “Image elements do not have explicit width and height” diagnostic identifies exactly which images need fixing.

Lazy Loading: The Right Way

Lazy loading delays image downloads until the image is about to enter the viewport. Images below the fold don’t load until the user scrolls near them — saving bandwidth and reducing initial page load time.

Page layout showing above-fold hero image loaded eagerly with high priority in green, and below-fold images lazy loaded in grey waiting to be scrolled into view
The hero image (your LCP element) must load eagerly with fetchpriority=”high”. Everything below the fold should be lazy loaded — but never your LCP image.

Native lazy loading: HTML now supports lazy loading natively: <img loading="lazy">. WordPress 5.5+ adds loading="lazy" to images automatically. No plugin needed. Browser support is universal in 2026. This is the recommended approach — zero JavaScript overhead, handled entirely by the browser.

The critical exception — the LCP image: Never lazy load the image that’s your Largest Contentful Paint element. This is typically your hero image, main product photo, or featured blog image — the largest visible image in the initial viewport. Lazy loading the LCP image delays its download, which directly increases your LCP time and tanks your PageSpeed score.

WordPress 6.3+ handles this intelligently: it automatically omits loading="lazy" from the first content image on each page (which is usually the LCP image). But verify this on your site — if your LCP image has loading="lazy", remove it manually or use the wp_img_tag_add_loading_optimization_attr filter.

The fetchpriority Attribute

While removing loading="lazy" from the LCP image prevents delayed loading, you can go further with fetchpriority="high". This attribute tells the browser to prioritise downloading this image above other resources.

<img src="hero.webp" width="1200" height="540" fetchpriority="high" alt="...">

By default, the browser downloads images at a lower priority than CSS and JavaScript. With fetchpriority="high", the LCP image downloads alongside critical CSS — starting earlier and finishing sooner. Your hero image is almost certainly your LCP element — fixing it is the single biggest Core Web Vitals win. This can improve LCP by 200–500ms on typical pages. WordPress 6.3+ adds fetchpriority="high" automatically to the first content image, but it’s worth verifying on your site.

CDN Image Delivery

Image CDN services go beyond static file caching — they optimise, resize, and convert images on the fly at the edge.

Cloudflare Polish: Automatically compresses images (lossy or lossless) and converts to WebP for supported browsers. Available on Pro plans and above ($20/month). Zero configuration needed — it processes images transparently at the CDN edge. Effective but less flexible than dedicated image CDNs.

Dedicated image CDNs (Imgix, Cloudinary, BunnyCDN Image Processing): These services allow URL-based image transformation — resize, crop, format conversion, and quality adjustment via URL parameters. For example: cdn.example.com/image.jpg?w=400&format=webp&quality=80. Powerful for dynamic sites that need different image sizes for different contexts, but adds a service dependency and ongoing cost.

ShortPixel Adaptive Images: A WordPress-specific image CDN that serves WebP/AVIF at the optimal size for each visitor’s viewport. The plugin replaces your image URLs with CDN URLs automatically. Free tier includes 5,000 images/month. A good middle-ground between plugin-based optimisation and full CDN services.

Bulk Optimisation for Existing Media Libraries

If you have an existing WordPress site with hundreds or thousands of unoptimised images, bulk optimisation is essential. Here’s the practical approach:

Step 1: Audit. Check your current media library size. In the terminal: du -sh wp-content/uploads/. Check the average image size and format — if most images are PNG or full-size JPEG, there’s significant room for optimisation.

Step 2: Choose a tool. ShortPixel and Imagify both support bulk optimisation. ShortPixel’s bulk optimiser processes images in the background — queue all images, let it run overnight. Imagify works similarly but with monthly quota limits on the free tier.

Step 3: Optimise. Start with lossy compression at quality 80 (or “glossy” in ShortPixel). Enable WebP conversion. The plugin processes each image, replaces the original with the compressed version, and generates a WebP alternative. Original images are backed up in case you need to restore them.

Step 4: Regenerate thumbnails. After bulk optimisation, regenerate WordPress thumbnails to ensure all sizes are optimised: wp media regenerate --yes. This ensures not just the full-size image but all thumbnail sizes benefit from the compression.

Expected results: A media library that was 2GB before optimisation typically drops to 400–600MB — a 70–80% reduction with no visible quality loss. Individual image file sizes drop from 200–500KB to 30–80KB. Images are just one item on our full optimisation checklist — but they’re usually the highest-impact one.

WordPress Thumbnail Sizes: Cleaning Up the Mess

WordPress generates multiple sizes for every uploaded image. Core creates thumbnail (150×150), medium (300×300), medium_large (768×768), and large (1024×1024). Your theme may add custom sizes. Plugins (WooCommerce adds several) may add more. A single uploaded image can generate 8–12 resized versions.

If you’ve changed themes or removed plugins, you likely have orphaned image sizes — resized versions that are no longer needed by any template but still consume disk space and slow down the upload process.

Audit registered sizes: Run wp eval 'print_r(wp_get_registered_image_subsizes());' to see every registered size. Identify which sizes your theme actually uses by checking template files for the_post_thumbnail('size-name') or wp_get_attachment_image_src($id, 'size-name').

Remove unused sizes: If sizes are registered by plugins you’ve removed, they won’t be generated for new uploads. For existing images, you can clean up orphaned sizes using the WP-CLI media regenerate command with the --image_size flag, or use a plugin like Jeune Image Resizer to remove specific sizes.

Frequently Asked Questions

Should I use WebP or AVIF for WordPress images?

Use WebP as your primary format — it’s supported by 97%+ of browsers and every WordPress optimisation tool handles it. AVIF offers 15–20% better compression than WebP but has slightly lower browser support (92%) and slower encoding. Consider AVIF as an additional format (served via <picture> element) for maximum performance, with WebP as the fallback.

What compression quality should I use for WordPress images?

Quality 80 for WebP and JPEG is the optimal sweet spot. Below 70, compression artefacts become visible. Above 85, file sizes increase significantly with negligible quality improvement. ShortPixel’s “glossy” setting and Imagify’s “aggressive” mode both target this optimal range automatically.

How do I stop my hero image from lazy loading?

WordPress 6.3+ automatically skips lazy loading on the first content image. If your hero image still has loading="lazy", add fetchpriority="high" and remove the lazy attribute in your theme template. You can also use the wp_img_tag_add_loading_optimization_attr filter to control which images are eagerly loaded.

Is it worth paying for an image optimisation plugin?

For sites with more than 100 images, yes. ShortPixel at $4.99 for 5,000 credits handles most small-to-medium sites for months. The time saved versus manual optimisation pays for itself immediately. The free tiers (ShortPixel: 100/month, Imagify: 20MB/month) are adequate for small sites with low upload frequency.

Do I need to manually set width and height on every image?

Images inserted through the WordPress editor automatically get width and height attributes. You only need to manually add them to images in custom theme templates, page builder output, or hardcoded HTML. Run PageSpeed Insights and check for the “Image elements do not have explicit width and height” diagnostic to find images that need fixing.

Images dragging your PageSpeed score down?

VeloPress optimises every image and configures proper delivery

WebP conversion, compression, responsive srcset, lazy loading (with LCP exclusion), fetchpriority, and CDN delivery. We typically reduce image payload by 70–80% with zero visible quality loss.

Get Your Free Audit →
View Pricing
Jamie McKaye

Jamie McKaye

Founder, VeloPress

Founder of VeloPress. 18 years in digital marketing, SEO, and web performance engineering. Optimised 150+ WordPress sites to score 95-100 on PageSpeed Insights. Based in Surrey, UK.

Get Started

Still struggling with WordPress speed?

VeloPress fixes this every day. We'll diagnose exactly what's slowing your site down and build a plan to hit 90+ on PageSpeed Insights.

Get Your Free Audit View Pricing

See what a full audit looks like — view sample report