How to Optimize Images for the Web
Images dominate page weight. How to optimise them with modern formats, compression, correct sizing, responsive images and lazy-loading to speed up your site.
If you only optimise one thing on your website, optimise the images. On most sites they are the single largest contributor to page weight, which means they are also the largest, easiest opportunity to make the page faster — usually with no visible loss of quality. In short: serve modern formats (AVIF or WebP), size each image to how it is actually displayed, compress it, use responsive images and lazy-loading, and always set dimensions to prevent layout shift. Done well, this single pass can remove a large share of a page's bytes. This guide walks through every step, with a format comparison table and concrete tools.
It is one of the biggest levers in how to make your website load faster.
Why images dominate page weight
The HTTP Archive's Web Almanac, which analyses millions of real pages, consistently finds that images make up a large share of the bytes a typical page transfers — often the biggest single category. That is intuitive: a single high-resolution photo can outweigh all of a page's HTML, CSS and text combined. The consequences cascade. Heavy images slow the page down, drag on Largest Contentful Paint (since the hero image is frequently the LCP element), burn through mobile data plans, and increase the energy used to deliver the page — which raises its carbon footprint. Because the impact is so large and the fixes are so well understood, image optimisation is the highest-return performance work most teams can do.
Choose the right format
Format is the first big decision, and modern formats compress dramatically smaller than the old ones at equivalent quality.
| Format | Best for | Notes |
|---|---|---|
| AVIF | Photographs, complex images | Usually the smallest files at a given quality; excellent compression; broad modern-browser support |
| WebP | Photographs, graphics, transparency | Much smaller than JPEG/PNG; very widely supported; great default |
| JPEG | Photographs (fallback) | Universal support; larger than WebP/AVIF; use as a fallback |
| PNG | Lossless, sharp edges, transparency | Large files; reserve for cases WebP/AVIF cannot cover |
| SVG | Logos, icons, simple graphics | Tiny vector format; scales infinitely without quality loss; not for photos |
A robust strategy is to serve AVIF or WebP with a JPEG/PNG fallback using the <picture> element, so modern browsers get the small file and older ones still work. For anything that is a logo, icon or simple illustration, reach for SVG first — it is usually a fraction of the size of a raster equivalent and stays crisp at any resolution.
A few practical nuances are worth knowing. AVIF generally wins on file size, but it can be slower to encode and, at very aggressive settings, can smear fine detail and gradients in ways that show up on large hero images — so test it on your actual content rather than trusting a single benchmark. WebP is the pragmatic middle ground: nearly universal support, big savings over JPEG and PNG, and fast, predictable encoding. PNG still has a place for screenshots of text and UI, where its lossless nature keeps edges crisp, though lossless WebP often matches it at a smaller size. And SVG, because it is just text-based markup, should be minified (and ideally compressed with gzip or Brotli) like any other text asset; an unoptimised SVG exported from design software can carry surprising bloat in metadata and redundant paths.
Compress: lossy vs lossless
Compression reduces file size by removing data. Lossy compression (JPEG, and the lossy modes of WebP/AVIF) discards information the eye barely notices, achieving large savings; the trick is to find the quality level where the file is small but the image still looks clean — often much lower than people expect. Lossless compression (PNG, lossless WebP) preserves every pixel but saves less. For photographs, lossy at a sensible quality is almost always the right call. The practical advice: do not ship images at maximum quality out of habit. Test a few quality levels side by side and pick the lowest that still looks good — the byte savings between "perfect" and "indistinguishable from perfect" are frequently enormous.
Size images correctly
This is where huge amounts of waste hide. If an image is displayed in an 800-pixel-wide slot but you upload a 4000-pixel original, the browser downloads the full 4000-pixel file and then shrinks it on screen — you paid for roughly 25 times the pixels you needed. Resize each image to the largest dimensions it is actually displayed at. Account for high-density (retina) screens by providing roughly 2x the CSS pixel dimensions for those devices, which still looks sharp without serving needlessly enormous files. Correct sizing alone often saves more bytes than compression does.
Serve responsive images
Different devices need different sizes, and responsive images let you serve each the right one rather than a single compromise file.
srcsetandsizeson an<img>give the browser a set of image widths and tell it how wide the image will display, so it picks the smallest file that still looks sharp for that device and screen density. A phone downloads a small file; a large desktop downloads a larger one.- The
<picture>element lets you go further — serving different formats (AVIF/WebP with a fallback) or even different crops at different breakpoints (art direction), for example a tighter crop on mobile.
Responsive images are one of the most effective image optimisations because they stop you sending desktop-sized photos to phones, which is otherwise extremely common.
Lazy-load below-the-fold images
Images the user has not scrolled to yet do not need to load during the initial render. Adding loading="lazy" to off-screen images defers their download until the user scrolls near them, which speeds up the initial load and saves bandwidth for visitors who never reach the bottom of the page.
One critical exception: never lazy-load your LCP image. The largest above-the-fold image is usually the element Largest Contentful Paint measures, and lazy-loading it tells the browser to delay the very thing being timed. Load that image eagerly — ideally preloaded with fetchpriority="high" — and lazy-load everything below it.
Always set dimensions to prevent layout shift
Set explicit width and height attributes (or a CSS aspect-ratio) on every image. This lets the browser reserve the correct space before the image arrives, so the page does not jump when it loads — the most common cause of poor Cumulative Layout Shift. It costs nothing and prevents a whole category of layout-shift problems, so make it a non-negotiable habit on every image you add.
Deliver images efficiently with a CDN
A content delivery network serves images from an edge server close to each visitor, reducing latency. Image CDNs go further: tools like Cloudflare Images, Cloudinary and imgix can automatically convert to the best format the browser supports, resize to the requested dimensions, and compress — all on the fly — so you can store one high-quality original and let the CDN derive optimised variants per request. For sites with many images this removes a lot of manual work and keeps every image consistently optimised.
The tools
- Squoosh — a free browser tool from Google; compare formats and quality with a live before/after preview. Ideal for understanding the trade-offs and for one-off images.
- ImageOptim — batch, lossless (and optional lossy) compression on macOS; drag a folder in and it strips waste.
- sharp — a fast Node.js image-processing library for automating resize, format conversion and compression at build time or on the server.
- Image CDNs (Cloudflare Images, Cloudinary, imgix) — automatic, per-request optimisation and format negotiation.
For build-driven sites, framework image components (such as those in Next.js and similar frameworks) wrap many of these best practices — sizing, formats, lazy-loading and dimensions — into a single component, which is the easiest way to get them right consistently.
Common real-world scenarios
Most image problems fall into a few recognisable patterns, and naming them makes them easier to fix:
- The giant hero. A beautiful full-width banner exported straight from a design tool at 3000px and 2MB. It is almost always the LCP element, so it is the worst place to be heavy. Resize it to its real display width, convert to AVIF/WebP, compress hard, and preload it.
- The CMS upload free-for-all. Editors upload phone photos at full resolution directly into articles. The fix is process plus tooling: resize on upload (most CMSes and image CDNs can do this automatically) so no single careless upload can bloat a page.
- The icon sprite that should be SVG. Interface icons shipped as PNGs, sometimes at multiple resolutions. Replacing them with inline or sprited SVG cuts bytes and keeps them sharp on every screen.
- The decorative background nobody needs. Large background images used purely for atmosphere. Question whether they earn their weight at all; if they stay, compress them aggressively, since decoration rarely needs pixel-perfect fidelity.
Spotting which pattern you have tells you which fix to reach for first, rather than treating every image the same way.
A step-by-step workflow
- Audit which images dominate page weight (PageSpeed Insights and the DevTools Network panel both make this clear).
- Resize each to the largest dimension it is displayed at, with a 2x variant for retina.
- Convert to AVIF or WebP, keeping a JPEG/PNG fallback via
<picture>; use SVG for logos and icons. - Compress at the lowest quality that still looks clean — test a few levels.
- Add responsive
srcset/sizesso each device gets an appropriate file. - Lazy-load below-the-fold images; load the LCP image eagerly (preload + high priority).
- Set
width/heighton everything to prevent layout shift. - Re-measure and, where practical, automate the pipeline so new images stay optimised.
Common mistakes
- Uploading full-resolution originals and letting the browser scale them down.
- Sticking with JPEG/PNG when AVIF/WebP would be a fraction of the size.
- Lazy-loading the hero/LCP image, delaying the main content.
- Omitting width and height, causing layout shift.
- Optimising once instead of automating, so the site bloats again over time.
Go deeper
- The big picture, in priority order: how to make your website load faster.
- The metric your hero image drives: what is Largest Contentful Paint.
- Why dimensions matter: what is Cumulative Layout Shift and how to fix it.
- The sustainability angle: what is a website carbon footprint and how to reduce it.
Want to see which images are slowing your site, alongside SEO, security and AI-readiness? Analyse any URL with StackOptic — free, no sign-up.
Frequently asked questions
Why is image optimization important?
Because images are typically the largest part of a web page's total weight — the HTTP Archive's Web Almanac consistently shows images accounting for a large share of bytes transferred. Heavy images slow loading, hurt Largest Contentful Paint, cost mobile users data, and increase a site's energy use and carbon footprint. Optimising images usually delivers the biggest, easiest performance win available, often without any visible loss of quality.
What is the best image format for the web?
For photographs, AVIF generally gives the smallest files at a given quality, with WebP a strong, widely supported alternative; both beat JPEG. Use PNG only when you need lossless quality or transparency that WebP/AVIF cannot cover, and use SVG for logos, icons and simple graphics because it is a tiny, infinitely scalable vector format. A good approach is to serve AVIF or WebP with a JPEG/PNG fallback via the picture element.
What size should my images be?
Size each image to the largest dimensions it is actually displayed at, accounting for high-density (retina) screens by serving roughly two times the CSS pixel size for those devices. Serving a 4000-pixel-wide image into an 800-pixel slot wastes most of the downloaded bytes. Combine correct dimensions with responsive images (srcset/sizes) so phones receive small files and large screens receive larger ones, rather than everyone getting one oversized image.
Should I lazy-load images?
Yes, for images below the fold. Adding loading="lazy" to off-screen images defers their download until the user scrolls near them, saving bandwidth and speeding up the initial load. But never lazy-load your largest above-the-fold image — typically the LCP element — because that delays the very content Largest Contentful Paint measures. Load that one eagerly, ideally preloaded with high fetch priority.
What tools can I use to optimize images?
For one-off images, Squoosh (a free browser tool from Google) lets you compare formats and quality with a live preview, and ImageOptim handles batch compression on a Mac. For automated pipelines, the sharp library processes images at build time or on the server, and many CDNs and image CDNs (such as Cloudflare Images, Cloudinary or imgix) convert format, resize and compress on the fly based on the requesting device.
Analyse any website with StackOptic
Get the full technology stack, performance, security and SEO report in seconds — free.
Analyse a websiteRelated articles
How to Test Your Website Speed (Tools and Metrics)
Which tools to use, lab versus field data, and the metrics that matter. Test your site speed with PageSpeed Insights, Lighthouse, WebPageTest and DevTools.
How to Optimize CSS for Faster Pages
CSS is render-blocking, so bloated stylesheets delay your page. How to minify, cut unused CSS, inline critical CSS and defer the rest to speed up FCP and LCP.
What Are Gzip and Brotli Compression (and How to Enable Them)?
Gzip and Brotli shrink HTML, CSS and JavaScript before they are sent. What each is, how Brotli compares to Gzip, how to verify it, and how to enable it.