/ Image Optimisation Fixes / Fix Images in WordPress

How to Fix Images in WordPress: Compression, WebP, Lazy Loading

WordPress sites carry image weight badly by default — high-megapixel uploads, theme template images without optimisation, page builder photo backgrounds, gallery duplicates. This guide covers the full WordPress image-optimisation workflow: bulk-compress the media library, convert to next-gen formats (WebP/AVIF), verify responsive srcset works, configure lazy loading correctly, add CDN delivery and backfill alt text. Combine with CLS fixes for full Core Web Vitals coverage and our image guide for theory.

Step 1: Audit existing images

Before optimising, measure. Run PageSpeed Insights on 5 representative pages and look at the "Opportunities" section — it lists "Properly size images", "Efficiently encode images", "Serve images in next-gen formats" with specific URLs and predicted savings in KB. Also use our Image Optimisation tool for a full site-wide scan that returns every image with size, format, dimensions and alt-text status.

Note the worst offenders. Typically you'll find: a 4000×3000px hero image displayed at 1200px wide (2-3MB when it should be 200KB), a series of uncompressed PNG screenshots in blog posts (5MB+ each), and dozens of media-library uploads missing alt text.

Step 2: Bulk-compress the media library

Install one image optimisation plugin (don't run multiple — they conflict). The three main choices:

ShortPixel — best compression ratios. Free tier: 100 images/month. Paid plans from $4.99/month for 5,000 images. Configure: lossy compression, 80% quality, keep originals as backup, generate WebP automatically.

Smush — easiest UI. Free version: unlimited compression but lossless only. Smush Pro ($7/month) adds lossy and CDN. Good for non-technical users.

Imagify — by WP Rocket. Free tier: 20MB/month. Paid plans from $9.99/month. Tightest integration with WP Rocket caching.

Whichever plugin you pick: enable "keep original backup" before running bulk compression. Without backup, compression is destructive. Run bulk-compress on a quiet day — the queue can take hours for large libraries.

Step 3: Convert to WebP and AVIF

WebP is 25-35% smaller than JPEG at equivalent quality with 98% browser support. AVIF is another 20% smaller again with 92% support. The serving stack you want:

  1. Browser sends Accept header listing supported formats
  2. Server checks: AVIF? Serve .avif. WebP? Serve .webp. Otherwise serve .jpg
  3. Done via .htaccess rules or a plugin that handles content-negotiation

Easiest implementation: ShortPixel's "Deliver WebP" toggle + Cloudflare Polish for AVIF. Or use a CDN like BunnyCDN with image optimisation enabled — it negotiates format at the edge.

Step 4: Verify srcset for responsive images

WordPress automatically generates multiple image sizes on upload and outputs them as srcset attributes. View source on a blog post and confirm your img tags look like this:

<img src="image-1024x768.jpg"
     srcset="image-300x225.jpg 300w,
             image-768x576.jpg 768w,
             image-1024x768.jpg 1024w,
             image-1536x1152.jpg 1536w"
     sizes="(max-width: 1024px) 100vw, 1024px"
     width="1024" height="768" alt="..." />

If srcset is missing: your theme is stripping it (audit theme functions.php for filters like wp_calculate_image_srcset), or your page builder is outputting raw URLs without WordPress's image function. Edit theme/builder output to use wp_get_attachment_image() which always produces srcset.

Step 5: Enable native lazy loading correctly

WordPress 5.5+ automatically adds loading="lazy" to img tags below the fold. Verify in view-source. Three common breakage patterns:

Hero images marked lazy. Above-the-fold hero images should NOT be lazy — they delay LCP. WordPress's auto-detection sometimes mislabels them. Override by adding loading="eager" manually on the hero img tag, or use the wp_lazy_loading_enabled filter to disable lazy for above-fold contexts.

Page builder override. Elementor and Divi sometimes output their own lazy-loading attribute that conflicts with WP's native one. Check the builder image module settings — usually a "Native lazy load" toggle.

Plugin double-lazy. A3 Lazy Load and similar plugins were essential before WP 5.5; now they conflict with native lazy. Disable third-party lazy plugins; let WP core handle it.

Step 6: Add CDN delivery

Images served from your origin server take 200-400ms longer to load than images from a global CDN, particularly for international visitors. Easy wins:

Cloudflare (free) — sign up, change nameservers, enable Polish for image optimisation, enable WebP. Done. Cloudflare Mirage further optimises images for mobile.

BunnyCDN ($1/month base) — install the BunnyCDN WordPress plugin, point at your origin, enable image optimisation. Faster than Cloudflare in some regions, cheaper at scale.

KeyCDN — similar to BunnyCDN. Plugin handles URL rewriting.

Step 7: Backfill alt text

Alt text matters for accessibility (screen readers), SEO (image search ranking) and AI visibility (engines extract alt text as image context). Audit your media library — most WordPress sites have 30-60% missing alt text. Tools:

Use a bulk alt-text plugin like "Auto Alt Text for Images" which applies AI-generated descriptions, or work through manually for higher quality. Either way, prioritise: featured images and in-content blog images first (highest SEO value), then media library backfill. Decorative images get alt="" (empty), never omit the attribute entirely.

💡 After every WordPress core update, re-test 3-5 image URLs in view-source. WordPress 5.5, 5.7, 6.0 and 6.4 all changed image-handling defaults — your plugin configuration may need adjusting after each major update.

Frequently Asked Questions

Which image plugin is best for WordPress: Smush, ShortPixel or Imagify?
ShortPixel offers the best compression ratios in independent tests, with cleanest WebP support and a generous free tier (100 images/month). Smush is the easiest UI and Smush Pro adds CDN. Imagify (by WP Rocket) integrates tightly with caching. For most sites ShortPixel free tier is sufficient up to a few thousand images; beyond that the choice is preference.
Should I use WebP, AVIF or both?
Both. WebP has 98% browser support and is the safe default. AVIF has 92% support and produces 20% smaller files than WebP at equivalent quality but requires more CPU to encode. Best practice: serve AVIF first, fall back to WebP, fall back to JPEG. Most modern image plugins handle this stack automatically.
Why are my WordPress images still huge after compressing?
Three common causes. First, srcset isn't working — your theme might force a single large size. Second, the original uploaded images were oversized and your compression plugin only compresses display sizes, leaving the original 4000px file referenced. Third, you uploaded screenshots which compress poorly — convert these to PNG-8 or run through TinyPNG specifically.
Does lazy loading actually help WordPress SEO?
Yes, but only when done correctly. Lazy-loading below-the-fold images improves LCP (Largest Contentful Paint) which is a Core Web Vital ranking signal. Lazy-loading above-the-fold images HURTS LCP because the hero image waits to load. WordPress 5.5+ does this correctly by default; check that page builders haven't overridden the rule.
Can I undo image compression if the result looks bad?
Plugins like ShortPixel and Smush keep an original-backup option. Enable it before bulk-compressing — disk space cost in exchange for reversibility. Without backup, the compression is destructive. Best practice: compress a test batch of 20 images first, eyeball the result on a high-DPI screen, then bulk-compress the rest.

🖼️ Audit your WordPress images first

Site-wide scan reveals every oversized, uncompressed and alt-text-missing image.

Run Image Audit →
Related Guides: Image Optimisation Guide  ·  All Image Fixes  ·  Page Speed Guide  ·  Fix CLS in WordPress
💬 Got a problem?