Pular para o conteúdo
PerformanceImagesOptimization

Image Optimization for E-commerce: Formats, Sizes and Lazy Loading

9 min

Images account for 50-70% of total page weight in e-commerce. A typical PDP has 5 to 15 product images, recommendation thumbnails, banners and icons. If not optimized, these images can easily total 5-10MB per pageview. On mobile with 4G, this means 10-15 seconds just to load images. Image optimization is simultaneously the highest impact action and the simplest to implement. It does not require architecture changes, does not break functionality and results are immediate. A store that never optimized images can reduce page weight by 60-80% with correct techniques. This article covers all aspects: modern formats, responsive images, lazy loading, image CDN, blur placeholders and specific best practices for product images. Each technique includes practical implementation and expected impact.

WebP vs AVIF vs JPEG: when to use each format

JPEG: the legacy format. Lossy compression with configurable quality. Supported by all browsers forever. Use only as fallback for browsers that do not support modern formats (practically none in 2025). Quality 80 is a good balance between size and visual quality. WebP: developed by Google. Offers 25-35% size reduction vs JPEG with equivalent visual quality. Support in all modern browsers (97%+ globally). Supports transparency (replaces PNG) and animation (replaces GIF). It is the recommended default format for e-commerce in 2025. Use quality 80-85 for product images. AVIF: based on AV1 codec. Offers 40-50% reduction vs JPEG. Superior visual quality at smaller sizes. The trade-off: slower encode (3-10x vs WebP) and smaller browser support (87% globally, no old Safari). For static images that can be pre-processed at build, AVIF is excellent. For dynamic images needing real-time processing, WebP is more practical. Recommended strategy: AVIF as first option (picture element with source type image/avif), WebP as second option (source type image/webp), JPEG as fallback (img tag). Image CDNs like Cloudinary, imgix and Shopify CDN do this negotiation automatically via Accept header. Real numbers: a 1200x1200 product image occupying 350KB in JPEG becomes 240KB in WebP and 180KB in AVIF. Multiplied by 10 images on PDP, the difference is 3.5MB (JPEG) vs 1.8MB (AVIF). Almost 50% reduction in total page payload.

Responsive images: srcset and sizes in practice

Serving the same 1920px image to a 375px phone is pure waste. The phone downloads 4x more data than needed and discards the extra pixels. Responsive images solve this by serving the correct size for each device. srcset: defines multiple versions of the same image at different sizes. The browser chooses the most appropriate based on viewport width and pixel density (DPR). Example: img srcset product-400.webp 400w, product-800.webp 800w, product-1200.webp 1200w sizes (max-width: 768px) 100vw, 50vw. sizes: tells the browser what the display size of the image will be at each breakpoint. Without sizes, the browser assumes the image occupies 100vw and may choose a larger size than necessary. Define sizes that reflect the actual layout. Recommended breakpoints for e-commerce: 400px (mobile small), 600px (mobile large), 800px (tablet), 1200px (desktop), 1600px (desktop retina). Generate all variants at build or via image CDN. Real impact: a PDP serving 1200px images to all devices switched to 400px on mobile. 70% reduction in image payload for 65% of traffic (mobile). LCP improved 1.2 seconds on mobile. DPR (Device Pixel Ratio): retina screens (DPR 2x) need images with double the pixels to look sharp. A 400px slot on retina screen needs 800px image. The browser calculates this automatically when srcset uses width descriptors (w). No manual intervention needed.

Lazy loading: strategies and pitfalls

Lazy loading defers loading of images not visible in the viewport until the user scrolls to them. Reduces initial payload and accelerates LCP by eliminating bandwidth competition. Native loading lazy: the loading lazy HTML attribute is supported by all modern browsers. Simple, no JavaScript, no configuration. The browser decides the loading threshold (typically 1250px below viewport in Chrome). For most cases, it is sufficient. Intersection Observer: for more granular control, use the Intersection Observer API. Allows defining custom threshold, rootMargin for pre-loading and callbacks for analytics. Useful when native loading does not meet specific requirements. Pitfall 1: lazy loading on LCP image. Never put loading lazy on the hero image or main product image. This delays download start until the image enters the viewport, adding hundreds of milliseconds to LCP. Only below-fold images should have lazy loading. Pitfall 2: lazy loading without dimensions. If the image has no width/height defined, the browser reserves 0px of space. When the image loads, layout jumps (CLS). Always define dimensions or use aspect-ratio in CSS. Pitfall 3: all carousel images lazy. If the carousel is above-the-fold, the first image should not have lazy. The rest should. The user does not see other images immediately. Pitfall 4: excessive eager loading. Do not put loading eager on all above-fold images. The browser already prioritizes viewport images. Eager is only needed when there is competition with other resources and you need to guarantee maximum priority.

Image CDN: Cloudinary, imgix, Sanity CDN and Shopify CDN

Image CDNs do transformation, optimization and delivery via URL parameters. They eliminate manual processing and ensure each user receives the ideal image for their device and connection. Cloudinary: the most complete. Resize, crop, automatic format (auto format), automatic quality (auto quality), face detection, background removal, overlays. Pricing per transformation and bandwidth. Ideal for stores with large catalogs needing complex transformations. imgix: focused on performance and simplicity. Real-time processing via URL, global CDN, automatic format. Fewer features than Cloudinary but faster processing. Pricing per bandwidth. Sanity CDN: if you already use Sanity as CMS, image CDN is included. Hotspot (focal point) defined in Sanity Studio, resize via URL parameters, automatic format. Excellent native integration but without advanced transformations. Shopify CDN: automatic for Shopify stores. Serves WebP automatically, resize via URL (append _400x400 to filename), global cache. Limited transformations but zero configuration. Practical implementation: instead of hosting images locally and serving the same file to everyone, configure the CDN to serve: ideal format (WebP/AVIF via Accept header), correct size (via width parameter in URL), optimized quality (auto quality adjusts per image), with aggressive cache (CDN edge + browser cache). Typical result: 60-80% reduction in image weight without perceptible visual loss. 1-2 hour setup. Immediate ROI.

Product images: specific best practices

Product images have specific requirements that differ from generic content images. White background: most marketplaces and Google Shopping require white background. Save as JPEG/WebP (not PNG) because white background does not need transparency. PNG with white background is 3-5x larger than JPEG with no visual benefit. Size consistency: all catalog images should have the same proportion (1:1 is the industry standard). This ensures uniform grid in listings and eliminates CLS. Configure automatic crop on CDN to ensure consistency even when the photographer delivers varied sizes. Zoom: images for zoom need higher resolution (2000-3000px on the longer side). But serve the zoom version only when user interacts. Do not load zoom images on initial load. Use a zoom component that loads high-resolution on demand. Multiple angles: PDPs with 5-10 images should load only the main image initially. Others load with lazy loading as user navigates carousel or clicks thumbnails. Alt text: every product image needs descriptive alt text for SEO and accessibility. Include product name, color, variant. Example: Nike Air Max 90 White Sneaker - Side view. Do not use empty or generic alt like product image. Main image preload: on PDP, preload the main product image (the LCP one). Thumbnails and alternate angles do not need preload. This ensures LCP loads first and others do not compete for bandwidth.

Blur placeholder and skeleton loading

Placeholders prevent layout shift (CLS) and provide immediate visual feedback while the final image loads. The page does not look empty or broken. Blur placeholder (LQIP): technique of generating a tiny (10-40 bytes in base64) extremely blurred version of the image. Displayed inline in HTML immediately and replaced by the final image when loaded. Transition is smooth and experience feels premium. Next.js Image supports blur placeholder natively (placeholder blur + blurDataURL). For custom implementation, generate blur hash at build with sharp or thumbhash. Blurhash: algorithm encoding a low-resolution image representation in a compact string (20-30 characters). Decoded on client to canvas. Smaller than base64 but requires JavaScript to decode. Lighter alternative for cases where base64 inline is too large. Skeleton loading: instead of blur, shows a rectangle with shimmer animation (moving gradient). Does not reveal anything about the image but provides feedback that content is loading. Simpler to implement (pure CSS) and works well for product grids where all images have the same size. Aspect-ratio: regardless of placeholder type, define aspect-ratio on image via CSS or container. This reserves correct space before image loads and eliminates layout shift. For 1:1 product images, use aspect-ratio: 1. For 16:9 banners, use aspect-ratio: 16/9. Ideal combination for e-commerce: main product image with blur placeholder (premium feel). Listing grid with skeleton shimmer (performance). Carousel thumbnails with fixed aspect-ratio (zero CLS).

Automation and image pipeline

Manual optimization does not scale. A store with 10,000 SKUs and 5 images per SKU has 50,000 images. Optimizing one by one is unfeasible. The solution is automation. Upload pipeline: when a new image is uploaded (via admin or integration), an automatic pipeline processes: resize to standard breakpoints (400, 800, 1200, 1600), conversion to WebP and AVIF, blur placeholder generation, quality optimization (auto quality), upload to CDN with cache headers. Tools: sharp (Node.js) for local processing, Cloudinary/imgix for processing via API, Sanity for processing integrated with CMS. Build-time optimization: for static sites or SSG, process images at build. next/image does this automatically. For frameworks without native optimization, use plugins like vite-imagetools or webpack image-minimizer-plugin. Automatic validation: add CI/CD checks that reject images above a maximum size (e.g.: 500KB for product, 200KB for thumbnail). Prevents unoptimized images from reaching production. Monitoring: track average image weight per page over time. If it starts rising, investigate. New unoptimized product images, heavy promotional banners or editorial content images are the usual culprits. Configure alerts when average weight exceeds a threshold defined in the performance budget.