2HAASStart a project
All posts

Guides

Image optimization for the web: a practical guide

Images are usually the heaviest part of a page. Resize them, compress them, serve modern formats and the right size per screen, and load them in the right order.

The 2HAAS team3 min read

On most websites, images account for more bytes than everything else together. A single photo straight from a camera or a design tool can outweigh the HTML, CSS and JavaScript of the whole page. That makes images the first place to look when a site is slow, and the place where a small effort pays the most.

Work through these steps in order. Each builds on the one before.

1. Resize to the size you display

A 4000 pixel photo shown in an 800 pixel slot wastes more than 90 percent of its pixels. The browser downloads all of them and then throws most away.

Export images at the largest size they will be displayed, allowing for high density screens. For a slot that is 800 CSS pixels wide, 1600 pixels is plenty.

2. Compress

After resizing, reduce the quality setting until you can see a difference, then go back one step. For photos, a quality of 75 to 85 is usually indistinguishable from the original. Squoosh and ImageOptim do this by hand, and sharp does it in a build script.

Remove metadata as well. Camera details and embedded thumbnails add weight and can reveal a location.

3. Use modern formats

WebP and AVIF give much smaller files than JPEG and PNG at the same quality. Serve them with a fallback for older browsers. The details are in WebP and AVIF: modern image formats with a fallback.

4. Send each screen the right size

A phone does not need the image a desktop monitor needs. With srcset and sizes, the browser chooses.

<img
  src="/img/room-800.webp"
  srcset="/img/room-480.webp 480w, /img/room-800.webp 800w, /img/room-1600.webp 1600w"
  sizes="(min-width: 60rem) 50vw, 100vw"
  alt="A bright living room with a grey sofa"
  width="1600"
  height="1067"
  loading="lazy"
/>
  • srcset lists the files and their widths.
  • sizes says how wide the image is displayed: half the viewport on large screens, the full width otherwise.

The browser combines the two with the screen's pixel density and downloads one file, the smallest that still looks sharp.

5. Reserve the space

Always set width and height. The browser then knows the shape of the image before it loads, and the page does not jump when it arrives.

6. Load in the right order

  • The main image at the top loads first. Give it fetchpriority="high" and do not lazy load it.
  • Everything below the first screen gets loading="lazy".

More on this in native image lazy loading.

7. Cache and deliver

  • Put a content hash in file names and cache them for a year. A changed image gets a new name, so nobody sees a stale copy.
  • Serve images from a CDN, close to the visitor.

Automate it

Nobody keeps doing steps 1 to 4 by hand. Choose one of two approaches:

  1. A build step. A script generates the sizes and formats from the originals on every build. This site works that way.
  2. An image CDN. You upload one original, and the service resizes, converts and caches each variant on request.

Either way, an editor uploads one good image and the pipeline handles the rest.

What to expect

Step Typical effect
Resizing oversized images The largest single saving
Compression 30 to 60 percent smaller files
Modern formats A further 25 to 50 percent
Responsive sizes Phones download a fraction of the desktop bytes
Lazy loading Far fewer requests on first load

Together these often cut image weight by 70 percent or more and bring a clear improvement in Largest Contentful Paint. To see where your own page stands, measure it with Chrome DevTools.

Keep reading

  1. Guides2 min read

    Find performance bottlenecks with Chrome DevTools

    Stop guessing why a page is slow. Use the Network and Performance panels in Chrome DevTools to find the heavy files, long tasks and layout shifts that cost you speed.

  2. Guides2 min read

    How to reduce JavaScript bundle size

    Every kilobyte of JavaScript is downloaded, parsed and run before a page responds. Measure the bundle, split it by route, lazy load the rest and trim dependencies.

  3. Guides4 min read

    Mastering Responsive Layouts with CSS Container Queries

    Learn how to implement CSS Container Queries for truly responsive, component-based layouts. This guide covers setup, syntax, and practical examples.

Tell us what’s in the way.

A few lines is enough. You get a candid yes, a candid no, or a sharper question.

  • Working software in week four
  • A reply in one business day
  • Handover is the deliverable

Prefer email? [email protected]

The problem, who it is for, and what is in the way right now.

One business day to a real reply. No sales sequence, no call required.