WooCommerce Image Speed: WebP/AVIF, Correct Sizes & Lazy-Load (No Bloat)
Author
John CavilIf your store looks great but LCP is slow and product pages feel heavy, your images are the culprit. This guide shows the fastest, low-risk path to fix WooCommerce images—right sizes, next-gen formats, lazy-load + priority hints—without piling on bloated plugins.
Why images slow WooCommerce (and how we’ll fix it)
- Oversized thumbnails → you ship 2000px where 400–800px would do.
- Wrong format → PNG/JPEG when WebP/AVIF cut bytes by 30–60%.
- Lazy-load everything → your LCP image gets lazy-loaded (don’t).
- Missing width/height → layout shifts (CLS).
- CDN misconfig → caches ignore device size or the
Acceptheader.
Goal: Serve exact-fit images in next-gen formats, load above-the-fold media early, and defer the rest—with stable layout.
Step 1 — Set the right WooCommerce image sizes
You want three buckets:
- Catalog/grid: 300–480px on the longest edge (depends on your grid).
- Single product (gallery/hero): 800–1200px typical; 1400–1600px if your theme is full-width/retina-heavy.
- Thumbnails: 150–300px.
Where to change sizes
- Block themes / Customizer → Appearance → Customize → WooCommerce → Product Images (or your theme’s options).
- Many modern themes expose “Main image width” and “Thumbnail width.” Pick values that match your layout (measure the actual rendered CSS width at desktop and mobile breakpoints).
Regenerate after changing sizes
- WP-CLI:
wp media regenerate --yes - Or use a lightweight regenerate plugin, run once, then deactivate.
Tip: Keep an eye on srcset that WordPress generates. Make sure the largest candidate isn’t way beyond your container width.
Step 2 — Use next-gen formats (WebP/AVIF) with fallback
- WebP: Great default—widely supported, small files.
- AVIF: Even smaller at the same quality (not always, but often).
- Fallback: Keep a JPEG/PNG fallback for rare edge cases (older Safari versions or specialty devices).
Three simple ways to serve next-gen
- Your CDN transforms on the fly (ideal): honors the
Acceptheader and returns WebP/AVIF. - Server-level conversion (e.g., ImageMagick + rules) with content negotiation.
- A lean plugin that generates WebP alongside JPEG and swaps sources on the front-end.
Must-haves:
- CDN/edge should vary cache by
Accept(so WebP users get WebP). - Keep EXIF stripping on for product shots unless your workflow needs metadata.
- Don’t “double-compress” (avoid stacking two optimizers).
Step 3 — Lazy-load correctly (and prioritize LCP)
Lazy-load is good—until you lazy-load the hero product image. That’s your LCP. Load it eagerly and tell the browser it’s important.
<img
src="/images/product-hero.webp"
width="1200" height="1200"
fetchpriority="high"
loading="eager"
alt="Product name"
/>
Rules of thumb
- Only the first, above-the-fold image gets
loading="eager"+fetchpriority="high". - Everything else (gallery thumbs, related products, below-fold images) →
loading="lazy". - Provide width and height (or use CSS
aspect-ratio) to prevent CLS. - For carousels, lazy-load off-screen slides only; prefetch the next slide if it appears quickly.
Step 4 — Give the browser good hints (srcset, sizes, preload)
WordPress emits srcset automatically; ensure your theme supplies a realistic sizes attribute so the browser picks the right candidate:
<img
src="/images/product-hero-1200.webp"
srcset="/images/product-hero-800.webp 800w,
/images/product-hero-1200.webp 1200w,
/images/product-hero-1600.webp 1600w"
sizes="(max-width: 768px) 90vw, (max-width: 1200px) 70vw, 1200px"
width="1200" height="1200"
fetchpriority="high" loading="eager" alt="Product name"
/>
Preload the exact hero size if your theme is certain about it:
<link rel="preload" as="image"
href="/images/product-hero-1200.webp"
imagesrcset="/images/product-hero-800.webp 800w, /images/product-hero-1200.webp 1200w"
imagesizes="(max-width: 1200px) 70vw, 1200px">
Step 5 — CDN rules that actually help stores
- Resize at edge: If your CDN supports on-the-fly resizing, request the exact dimensions you render.
- Vary on
Accept: Ensure cache keys separate WebP/AVIF and JPEG. - Cache busting: Append a version query (e.g.,
?v=2025-09) on deploys to invalidate old variants. - Immutable static: Serve product gallery assets with long-lived
Cache-Control: public, max-age=31536000, immutable. - Don’t transform SVG product icons (leave them as is).
- No CDN? Learn with Pofii Insights how to add your website to Cloudflare CDN.
Step 6 — Fix CLS in product galleries
- Always output width/height (or use CSS
aspect-ratio: 1/1;) on gallery slots. - Avoid late-loading carousels that change layout height.
- Reserve space for badges (sale, discount) so they don’t push text on load.
- Replace JS-injected image dimensions with static attributes when possible.
Step 7 — Validate the wins (takes 5 minutes)
- Lighthouse (Chrome DevTools) → check LCP and CLS on a product page.
- WebPageTest (3G/4G profile) → confirm hero image is requested first and in WebP/AVIF.
- Network panel → verify byte size dropped and that
content-typeis correct. - Repeat view → ensure CDN hits and fast TTFB.
Minimal checklist
- Set Woo image sizes (catalog/single/thumb) to match layout
- Regenerate thumbnails
- Serve WebP/AVIF with fallback; cache varies by
Accept - Mark only hero/LCP image as eager +
fetchpriority="high" - Lazy-load everything else
- Add
width/height(oraspect-ratio) to stop CLS - Use sensible
sizeswithsrcset - Enable CDN image resizing & long cache headers
- Re-test LCP/CLS after deploy
Troubleshooting (fast fixes)
- Blurry thumbnails → Your theme is stretching small thumbs. Increase thumbnail size, regenerate, and ensure
srcsetincludes a larger candidate. - AVIF/WebP not served → CDN isn’t varying by
Accept, or a plugin is forcing JPEG. Fix cache key / plugin config. - CLS spike on PDP → Missing width/height; gallery script changes layout height; badges injected late. Add static dimensions and reserve space.
- Hero loads late → It’s lazy-loaded or not prioritized. Set
loading="eager"+fetchpriority="high"and consider preloading the exact candidate.
FAQ
WebP or AVIF—what should I default to?
Default to WebP for broad compatibility; enable AVIF when your CDN can negotiate by Accept. If AVIF fails, it should transparently fall back to WebP/JPEG.
Do I still need an image plugin if my CDN does transforms?
Not necessarily. If your CDN handles resizing + next-gen at the edge and your theme emits good srcset/sizes, keep plugins minimal.
Will next-gen formats hurt SEO?
No—search engines crawl images fine. Improvements in LCP/CLS often help overall page experience signals.
How big should my product hero be?
Aim for the rendered width: 800–1200px on most themes, 1400–1600px for wide, retina-forward designs. Don’t ship 2–3× more than your container.
Leave a Comment