Images are the heaviest assets on most web pages. According to the HTTP Archive, images account for roughly 50% of the average page's total weight. For media-rich sites — portfolios, e-commerce stores, news publications, and marketing pages — that percentage can climb even higher. Unoptimized images are the single most common cause of slow page loads, poor Core Web Vitals scores, and frustrated users who bounce before your content even renders.
This guide is written for developers and technical marketers who want to understand image optimization at a deep level. We will cover formats, compression algorithms, responsive image techniques, lazy loading strategies, CDN configuration, and how all of this connects to Google's Core Web Vitals metrics that directly affect your search rankings.
Why Image Optimization Matters
The business case for image optimization is straightforward:
- Page speed: Google reports that 53% of mobile users abandon sites that take longer than 3 seconds to load. Images are usually the primary bottleneck.
- SEO rankings: Core Web Vitals — Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP) — are ranking factors. LCP is directly affected by image loading performance.
- Bandwidth costs: Serving unoptimized images wastes bandwidth, increasing hosting costs and penalizing users on metered connections.
- User experience: Fast-loading images create a smooth, professional experience. Slow-loading images create a janky, frustrating one.
- Conversion rates: Walmart found that for every 1-second improvement in page load time, conversions increased by 2%. Amazon reported that every 100ms of latency cost them 1% in sales.
Understanding Image Formats
Choosing the right format is the foundation of image optimization. Each format has different strengths, and using the wrong one can bloat your file sizes unnecessarily.
JPEG (Joint Photographic Experts Group)
JPEG is the workhorse of web photography. It uses lossy compression, meaning it discards some visual information to reduce file size. At quality settings of 75-85%, the visual loss is imperceptible to most viewers while achieving significant compression.
Best for: Photographs, complex images with many colors and gradients.
Not ideal for: Images with text, sharp edges, transparency, or flat colors.
PNG (Portable Network Graphics)
PNG uses lossless compression, preserving every pixel exactly. It supports transparency (alpha channel), making it essential for logos, icons, and images that need to overlay other content.
Best for: Logos, icons, screenshots, images with text, images requiring transparency.
Not ideal for: Photographs (file sizes will be much larger than JPEG).
WebP
Developed by Google, WebP supports both lossy and lossless compression, as well as transparency and animation. It typically achieves 25-35% smaller file sizes than JPEG at equivalent visual quality, and significantly smaller sizes than PNG for lossless images.
Best for: Almost everything. WebP is the recommended default format for modern web development.
Browser support: All modern browsers support WebP. Internet Explorer does not, but IE usage is negligible.
AVIF (AV1 Image File Format)
AVIF is the newest contender, based on the AV1 video codec. It offers even better compression than WebP — typically 20-30% smaller at equivalent quality. It supports HDR, wide color gamut, and transparency.
Best for: Maximum compression with high visual quality. Ideal for image-heavy sites where every kilobyte matters.
Browser support: Chrome, Firefox, and Safari support AVIF. Support is growing but not yet universal.
SVG (Scalable Vector Graphics)
SVG is a vector format, meaning it describes images mathematically rather than as pixels. SVG files are resolution-independent, typically tiny, and can be styled with CSS and manipulated with JavaScript.
Best for: Icons, logos, illustrations, simple graphics. Browse our vector library for SVG-ready assets.
Not ideal for: Photographs or complex images with many colors.
Compression Strategies
Lossy Compression
Lossy compression reduces file size by permanently removing visual information that the human eye is unlikely to notice. The key is finding the sweet spot where file size is minimized without visible quality degradation.
For JPEG, a quality setting of 75-85% is generally optimal. Below 70%, artifacts become noticeable. Above 90%, the file size increases dramatically with minimal visual improvement.
For WebP lossy, a quality setting of 75-80% typically produces excellent results.
For AVIF, quality settings of 60-70% often match JPEG at 80-85% visually while being significantly smaller.
Lossless Compression
Lossless compression reduces file size without any quality loss by finding more efficient ways to encode the pixel data. Tools like OptiPNG, PNGQuant, and lossless WebP can reduce PNG file sizes by 20-50% without changing a single pixel.
Tools and Automation
Manual compression does not scale. Integrate compression into your build pipeline:
- Sharp (Node.js): High-performance image processing library. Supports JPEG, PNG, WebP, AVIF, and TIFF.
- Squoosh CLI: Google's command-line image compression tool with support for all modern formats.
- ImageMagick: Versatile command-line tool for batch processing.
- Next.js Image Component: Automatically optimizes images at build time and serves them in modern formats.
- Cloudflare Polish: Automatic image optimization at the CDN level.
Responsive Images
Serving a single image size to all devices is wasteful. A 2400px-wide hero image is overkill for a 375px-wide mobile screen. Responsive images solve this by serving different sizes based on the device's viewport and pixel density.
The srcset and sizes Attributes
The HTML <img> element supports srcset and sizes attributes that let the browser choose the most appropriate image:
`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: 600px) 100vw, (max-width: 1200px) 50vw, 800px"
alt="Descriptive alt text"
width="1600"
height="900"
/>
`
The browser evaluates the sizes attribute to determine how wide the image will be displayed, then selects the smallest image from srcset that is at least that wide. This can reduce image payload by 50-70% on mobile devices.
The picture Element
The <picture> element provides even more control, allowing you to serve different formats and art-directed crops:
`html
<picture>
<source srcset="hero.avif" type="image/avif" />
<source srcset="hero.webp" type="image/webp" />
<img src="hero.jpg" alt="Descriptive alt text" width="1600" height="900" />
</picture>
`
This serves AVIF to browsers that support it, WebP to those that support WebP but not AVIF, and JPEG as the universal fallback.
Lazy Loading
Lazy loading defers the loading of off-screen images until the user scrolls near them. This dramatically improves initial page load time by reducing the number of requests and bytes transferred during the critical rendering path.
Native Lazy Loading
Modern browsers support native lazy loading via the loading attribute:
`html
<img src="photo.jpg" loading="lazy" alt="Description" width="800" height="600" />
`
This is the simplest approach and requires no JavaScript. The browser handles the intersection detection and loading automatically.
Important: Do not lazy-load images that are visible in the initial viewport (above the fold). These should load immediately to avoid hurting LCP. Only apply loading="lazy" to images below the fold.
Intersection Observer API
For more control over lazy loading behavior — custom thresholds, loading animations, placeholder strategies — use the Intersection Observer API:
`javascript
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, { rootMargin: '200px' });
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
`
The rootMargin of 200px starts loading images when they are within 200 pixels of the viewport, providing a buffer so images are loaded before the user actually sees them.
Preventing Layout Shift
Cumulative Layout Shift (CLS) measures how much page content moves around during loading. Images without explicit dimensions are a major cause of layout shift — the browser does not know how much space to reserve until the image loads, causing content to jump.
Always Specify Dimensions
Always include width and height attributes on your <img> elements:
`html
<img src="photo.jpg" width="800" height="600" alt="Description" />
`
Modern browsers use these attributes to calculate the aspect ratio and reserve the correct space before the image loads, eliminating layout shift.
CSS Aspect Ratio
For responsive layouts where the image width is fluid, use the CSS aspect-ratio property:
`css
img {
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
}
`
Placeholder Strategies
While images load, display a placeholder that matches the final image's dimensions:
- Solid color: The simplest approach. Use the image's dominant color as a background.
- Low-quality image placeholder (LQIP): A tiny, blurred version of the image (typically 20-40 bytes as a base64-encoded data URI) that gives users a preview of the content.
- BlurHash: An algorithm that encodes an image's color distribution into a short string, which can be decoded client-side into a beautiful gradient placeholder.
CDN and Caching
Content Delivery Networks
A CDN serves your images from edge servers geographically close to your users, reducing latency. Most CDNs also offer automatic image optimization:
- Format conversion: Automatically serve WebP or AVIF based on the browser's Accept header.
- Responsive resizing: Generate and cache multiple sizes on the fly.
- Quality optimization: Automatically adjust compression based on network conditions.
Cache Headers
Set aggressive cache headers for images since they rarely change:
`
Cache-Control: public, max-age=31536000, immutable
`
This tells browsers and CDNs to cache the image for one year. Use content-based hashing in filenames (e.g., hero-a1b2c3d4.jpg) to bust the cache when images are updated.
Core Web Vitals and Images
Largest Contentful Paint (LCP)
LCP measures when the largest visible content element finishes rendering. For most pages, this is a hero image. To optimize LCP:
- Preload the LCP image: Use
<link rel="preload">to tell the browser to fetch the hero image immediately. - Do not lazy-load the LCP image: It must load eagerly.
- Use modern formats: WebP and AVIF load faster due to smaller file sizes.
- Serve the right size: Do not serve a 4000px image for a 1200px container.
- Use fetchpriority="high": Signal to the browser that this image is critical.
`html
<link rel="preload" as="image" href="hero.webp" type="image/webp" />
<img src="hero.webp" fetchpriority="high" alt="Hero image" width="1200" height="675" />
`
Cumulative Layout Shift (CLS)
As discussed above, always specify image dimensions and use aspect-ratio containers to prevent layout shift.
Working with Stock Images
When you download images from a stock library like Depositphotos, they typically come in high resolution — often 4000-6000 pixels wide. This is great for print but far too large for web use. Always process stock images before deploying them:
- Resize to the maximum display size you need (typically 1200-2400px for full-width images).
- Convert to WebP or AVIF for web delivery, keeping the original JPEG as a fallback.
- Compress using the quality settings discussed above.
- Generate responsive variants at multiple widths (400, 800, 1200, 1600, 2400px).
- Strip metadata (EXIF data) to reduce file size, unless you need it for SEO or attribution.
Tools like our background remover can also help prepare images by isolating subjects, which often results in simpler images that compress more efficiently.
For teams that need to process large volumes of images programmatically, our API provides access to the full library with options to specify resolution and format at download time. Design teams can also use our plugins to streamline the workflow directly within their tools.
Automation and Build Pipelines
The most effective image optimization is automated. Here is a recommended pipeline:
- Source: Download high-resolution images from your stock library or receive them from photographers.
- Process: Run through an optimization pipeline (Sharp, Squoosh, or similar) that resizes, converts, and compresses.
- Generate: Create responsive variants and modern format alternatives.
- Deploy: Upload to your CDN with appropriate cache headers.
- Monitor: Track Core Web Vitals in production to catch regressions.
For Next.js projects, the built-in Image component handles most of this automatically. For other frameworks, tools like vite-plugin-image-optimizer or custom webpack loaders can integrate optimization into your build process.
Conclusion
Image optimization is not a one-time task — it is an ongoing practice that should be embedded in your development workflow. By choosing the right formats, implementing responsive images, lazy loading off-screen content, preventing layout shift, and leveraging CDNs, you can dramatically improve your site's performance, SEO rankings, and user experience.
The investment pays for itself many times over in faster load times, higher search rankings, better conversion rates, and lower bandwidth costs. Start with the highest-impact changes — format conversion and responsive images — and progressively implement the more advanced techniques as your optimization practice matures.
For high-quality source images to optimize, explore our photo, design asset, and AI image workflows. Check our pricing plans for options that fit your project's needs, or try our free files to get started. For more technical guides and creative insights, visit our blog regularly.



