Tutorial

How to Optimize Images for the Web in 2026

Images account for roughly 50% of the total bytes on the average web page, making them the single biggest opportunity for performance improvement. Unoptimized images are the most common cause of poor LCP scores. This guide covers every aspect of image optimization -- from format selection to responsive delivery -- with practical code examples you can implement today.

Typical file size comparison (same 1200x800 photo)

JPEG 280 KB WebP 180 KB (-36%) AVIF 140 KB (-50%)

Step-by-step guide

1

Choose the right image format

Format selection is the single highest-impact optimization. AVIF is the recommended format for photographic images -- it achieves ~50% smaller files than JPEG. WebP is the fallback for browsers without AVIF support (~7% of traffic). SVG is ideal for icons, logos, and illustrations. PNG should only be used when transparency is required and AVIF/WebP cannot handle the use case.

Use the HTML <picture> element to serve AVIF with automatic fallback to WebP and JPEG.

HTML -- Picture element with format fallback

  
  
  
  
  
  Descriptive alt text
2

Implement responsive images with srcset

The srcset attribute lets you provide multiple image sizes, and the browser automatically selects the smallest one that fits the user's screen and pixel density. The sizes attribute tells the browser the display width of the image at different viewport sizes, enabling accurate selection before CSS is loaded.

HTML -- Responsive image with sizes

Product photo

Tip: The sizes attribute is critical -- without it, the browser assumes the image is 100vw (full viewport width) and downloads the largest size. This wastes bandwidth on pages where images are displayed in columns or grids.
3

Set proper loading and priority attributes

Three attributes control how the browser loads images:

  • loading="eager" (default) -- loads immediately. Use for the LCP image.
  • loading="lazy" -- defers loading until near the viewport. Use for all below-fold images.
  • fetchpriority="high" -- boosts download priority. Add to the LCP image alongside loading="eager".

The combination of loading="eager" + fetchpriority="high" on the LCP image and loading="lazy" on everything else can improve LCP by 500ms or more by reducing network contention.

HTML -- Correct loading attributes

Hero


Feature 1

Feature 2


4

Always specify width and height

Adding width and height attributes to <img> elements allows the browser to calculate the aspect ratio and reserve space before the image loads. Without these, the image loads as a zero-height element and then expands, pushing surrounding content down -- a layout shift that directly increases CLS.

For responsive images that resize with CSS (width: 100%; height: auto;), the browser still uses the HTML attributes to compute the correct aspect ratio. Alternatively, use the CSS aspect-ratio property on the image container.

HTML + CSS -- Preventing layout shift

Photo


Photo
Photo
5

Use an image CDN for on-the-fly optimization

Image CDNs optimize images automatically at the edge, converting formats, resizing, and compressing based on the requesting browser's capabilities. Instead of generating multiple sizes at build time, you request the image with URL parameters and the CDN handles the rest.

HTML -- Cloudinary example

Hero image
Tip: Image CDN providers include Cloudinary, Imgix, Cloudflare Images, Bunny.net, and KeyCDN. Most offer generous free tiers sufficient for small to medium sites.
6

Use your framework's image component

Modern frameworks include image components that handle optimization automatically: <Image> in Next.js, <NuxtImg> in Nuxt, <Image> in Astro, and enhanced:img in SvelteKit. These components generate responsive srcsets, convert to modern formats, add dimensions, and configure lazy loading by default.

JSX -- Framework image components
// Next.js
import Image from 'next/image';
Hero

// Astro
import { Image } from 'astro:assets';
import hero from '../assets/hero.jpg';
Hero

// Nuxt


// SvelteKit
Tip: Framework image components handle the complexity of responsive images, format conversion, and proper loading attributes automatically. Always prefer them over raw <img> tags.

Frequently asked questions

Should I use AVIF or WebP for images?

Use AVIF as the primary format and WebP as the fallback. AVIF achieves approximately 50% smaller file sizes than JPEG and 20% smaller than WebP at equivalent visual quality. Browser support for AVIF is now at 93%+ (Chrome, Firefox, Safari 16+). Use the HTML picture element to serve AVIF with WebP and JPEG fallbacks for older browsers.

Does image lazy loading hurt LCP?

Lazy loading BELOW-fold images helps LCP by reducing network contention and allowing the browser to prioritize the LCP image. However, adding loading='lazy' to the LCP image itself is a common mistake that significantly harms LCP because the browser delays downloading it until it enters the viewport. Always set the LCP image to loading='eager' with fetchpriority='high'.

How much can image optimization improve LCP?

Image optimization is typically the highest-impact LCP improvement available. Converting from JPEG to AVIF can reduce image file size by 50%, which directly reduces download time. Adding responsive images prevents mobile devices from downloading 2-4x larger images than they need. Combined with proper preloading, these optimizations commonly improve LCP by 1-3 seconds.

Should I use an image CDN or optimize at build time?

Build-time optimization (Sharp, squoosh) works well for static sites with known images. Image CDNs (Cloudinary, Imgix) are better for dynamic content like user-uploaded images or CMS-managed media because they optimize on-the-fly. Many frameworks combine both: build-time optimization for local images and CDN integration for remote images.

What image dimensions should I use for responsive images?

A common set of responsive image widths is: 400w, 800w, 1200w, and 1600w. These cover mobile phones (360-414px viewports at 2x DPR = ~800px needed), tablets (768-1024px at 2x = ~1600px), and desktops (1200-1920px at 1-2x = ~1600-2400px). The sizes attribute tells the browser which size to download based on the current viewport width.

Sarah Kim

Frontend Developer at WebVitals.tools

Sarah focuses on image optimization and responsive design. She maintains performance optimization guides for Next.js, Astro, and SvelteKit.