Web Toolkit

Sizing and compressing images for the web

Most slow pages are slow because of one image. Fixing it is two decisions — dimensions, then format — taken in that order.

Last updated 30 July 2026

An image that is 4,000 pixels wide displayed in an 800-pixel column is not high quality. It is the same picture with 25 times the pixel data, downscaled by the browser after every visitor has already paid to download it. That single mistake is behind a large share of failing Largest Contentful Paint scores, and it is the cheapest performance problem there is to fix.

Two decisions fix it, and the order matters.

First decision: dimensions

Find the largest size the image is ever actually displayed at, in CSS pixels, then multiply by two for high-density screens. A hero that renders 1,200px wide wants a 2,400px source. A thumbnail shown at 200px wants 400px. Beyond 2× there is no visible benefit on any shipping display, and the file grows with the square of the dimension — doubling width quadruples the pixel count.

This is worth measuring rather than guessing: open the page, inspect the element, and read the rendered width. The number is almost always smaller than people expect, because layouts have max-widths and gutters that the original design mockup did not.

Never upscale. Enlarging a 400px image to 1,200px invents no detail and produces a soft, larger file. If the source is too small, the fix is a better source.

Second decision: format

  • WebP — the default choice for photographs and most graphics on the web today. Typically 25–35% smaller than a JPEG of comparable visual quality, supports transparency and animation, and is supported by every browser still receiving security updates.
  • JPEG — still correct for photographs that need to work everywhere, including old email clients, print workflows and systems that reject anything unfamiliar. Never for screenshots: JPEG's chroma subsampling smears the sharp edges of text into visible artefacts.
  • PNG — the right answer for screenshots, diagrams, logos, anything with flat colour, sharp edges or transparency. Lossless, and on text-heavy images frequently smaller than a JPEG that also looks worse. Wrong for photographs, where it can be several times larger than a JPEG nobody could distinguish from it.

AVIF compresses better again and is the right long-term target, but encoding is slow and support in older tooling is patchy — worth adopting deliberately rather than by default.

Do it in this order

Resize first, then convert. Encoding a 4,000px image as WebP and then shrinking it means the compressor spent its quality budget on detail you were about to throw away, and every lossy step compounds: the artefacts from the first encode become the input to the second. Downscale to the target dimension, then encode once.

For the same reason, keep the original. Every save of a lossy format loses information permanently, so edits should always start from the untouched file rather than from last week's export.

Quality settings

For JPEG and WebP, quality 75–85 is the useful range. Below 70 artefacts become visible on gradients and skin tones; above 90 the file grows quickly for differences almost nobody can see. The correct setting is per-image rather than universal — a flat graphic tolerates far more compression than a photograph of foliage, which is one of the hardest things to compress well.

Judge the result at the size it will actually be displayed, not zoomed to 400%.

What this buys you

Core Web Vitals treat the largest element in the initial viewport as the thing to measure, and on most pages that element is an image. Cutting a 2 MB hero to 180 KB moves LCP by a margin no amount of code-splitting will match. Two more habits that cost nothing:

  • Always set width and height (or an aspect-ratio) on the element. Without them the browser cannot reserve space, so the page reflows when the image lands — that is Cumulative Layout Shift, and it is entirely avoidable.
  • Lazy-load below the fold, and never lazy-load the hero. loading="lazy" on the LCP element delays exactly the thing being measured.

A note on privacy

Photographs carry EXIF metadata, which routinely includes GPS coordinates, the camera's serial number and a timestamp. Anything processed through a browser Canvas — which is how the resizer and converter here work — comes out stripped of that metadata as a side effect of being re-encoded from raw pixels. Convenient, but worth being deliberate about: if you need the metadata preserved, this is the wrong kind of tool, and if you need it gone, verify rather than assume.

Tools used in this guide

All guides