Back to Guides

Complete Image Optimization Guide

Compress, optimize, and serve images efficiently with modern formats, responsive techniques, and lazy loading for faster load times.

Why Image Optimization Matters

Images account for 50-70% of total page weight on most websites. Unoptimized images slow down Largest Contentful Paint (LCP), waste bandwidth, and frustrate users on slow connections. Proper image optimization can reduce page size by 60-80% while maintaining visual quality, dramatically improving Core Web Vitals and user experience.

Modern Formats

Use WebP and AVIF for 30-50% smaller file sizes.

Responsive Images

Serve different sizes for different devices and screens.

Lazy Loading

Load images only when they enter the viewport.

Compression

Reduce file size without visible quality loss.

1. Choose the Right Image Format

Different formats excel in different scenarios:

WebP: The Modern Standard

html
<!-- Use picture element for WebP with fallback -->
<picture>
<source srcset="hero.webp" type="image/webp">
<source srcset="hero.jpg" type="image/jpeg">
<img src="hero.jpg" alt="Hero image" loading="lazy">
</picture>
<!-- 25-35% smaller than JPEG, 26% smaller than PNG -->

AVIF: Next-Generation Format

html
<!-- AVIF offers even better compression -->
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Hero image">
</picture>
<!-- 50% smaller than JPEG, 20% smaller than WebP -->

Format Comparison

JPEG

Best for: Photographs, gradients. Avoid for: Graphics, text, transparency

PNG

Best for: Graphics, logos with transparency. Avoid for: Large photographs

WebP

Best for: Everything (97% browser support). 25-35% smaller than JPEG/PNG

AVIF

Best for: Modern browsers (90% support). 50% smaller than JPEG

SVG

Best for: Icons, logos, simple graphics. Scalable without quality loss

GIF

Avoid: Use video (MP4, WebM) for animations - 95% smaller file size

2. Compress Images Effectively

Reduce file size without noticeable quality loss:

Compression Tools

  • TinyPNG/TinyJPG - Web-based, excellent compression
  • ImageOptim - Mac app, lossless compression
  • Squoosh - Google's web app, visual comparison
  • Sharp (Node.js) - Automated compression in build pipelines

Quality Guidelines

typescript
// JPEG Quality Settings
Hero images: 85-90 quality
Product photos: 80-85 quality
Thumbnails: 70-75 quality
// WebP Quality Settings
Can go 5-10 points lower than JPEG for same visual quality
// AVIF Quality Settings
Can go 10-15 points lower than JPEG

Automated Compression with Sharp

javascript
const sharp = require('sharp');
// Convert to WebP with compression
await sharp('input.jpg')
.webp({ quality: 80 })
.toFile('output.webp');
// Generate multiple formats
await sharp('input.jpg')
.resize(1200, 800)
.toFormat('webp', { quality: 80 })
.toFile('hero.webp');
await sharp('input.jpg')
.resize(1200, 800)
.toFormat('avif', { quality: 65 })
.toFile('hero.avif');

3. Implement Responsive Images

Serve appropriately sized images for different devices:

Using srcset and sizes

html
<img
src="hero-800.jpg"
srcset="
hero-400.jpg 400w,
hero-800.jpg 800w,
hero-1200.jpg 1200w,
hero-1600.jpg 1600w
"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px"
alt="Hero image"
loading="lazy"
/>
<!-- Browser automatically selects best image for screen size -->

Art Direction with Picture

html
<!-- Different images for different breakpoints -->
<picture>
<source media="(max-width: 768px)" srcset="hero-mobile.jpg">
<source media="(max-width: 1200px)" srcset="hero-tablet.jpg">
<img src="hero-desktop.jpg" alt="Hero image">
</picture>

Image Sizing Guidelines

  • Mobile: 400-800px width
  • Tablet: 800-1200px width
  • Desktop: 1200-2000px width
  • Retina displays: 2x resolution (but compress more)

4. Lazy Load Images

Load images only when they're about to enter the viewport:

Native Lazy Loading

html
<!-- Modern browsers support native lazy loading -->
<img src="image.jpg" loading="lazy" alt="Description">
<!-- Load above-the-fold images immediately -->
<img src="hero.jpg" loading="eager" alt="Hero" fetchpriority="high">
<!-- 94% browser support, no JavaScript needed -->

IntersectionObserver for Advanced Control

javascript
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
observer.unobserve(img);
}
});
});
document.querySelectorAll('img.lazy').forEach(img => {
imageObserver.observe(img);
});

Lazy Loading Best Practices

  • Don't lazy load above-the-fold images (hurts LCP)
  • Always include width and height to prevent layout shifts
  • Use a placeholder (blur-up, LQIP) for better UX
  • Consider loading images 200-300px before they enter viewport

5. CDN and Caching

Serve images from a CDN for faster delivery:

Image CDN Benefits

  • Automatic format conversion (WebP, AVIF)
  • On-the-fly resizing and optimization
  • Global edge caching for faster delivery
  • Popular options: Cloudinary, Imgix, ImageKit, Cloudflare Images

Cache Headers

bash
# nginx configuration
location ~* .(jpg|jpeg|png|gif|webp|avif|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}

6. Background Images & CSS

Optimize CSS background images:

  • Use CSS gradients instead of images when possible
  • Lazy load background images with JavaScript
  • Use image-set() for responsive backgrounds
  • Compress background images heavily (they're often decorative)

Responsive Background Images

css
.hero {
background-image: image-set(
"hero-1x.webp" 1x,
"hero-2x.webp" 2x
);
}
@media (max-width: 768px) {
.hero {
background-image: image-set(
"hero-mobile-1x.webp" 1x,
"hero-mobile-2x.webp" 2x
);
}
}

Analyze Your Image Performance

Get AI-powered recommendations for image optimization and identify oversized images.

Analyze Your Website