Compressing images for the web: smaller files without losing quality
Images are usually the heaviest part of a web page. If your site is slow, the odds are good that the cause is a few oversized images rather than the code. The good news: this is one of the easiest performance problems to fix.
Step 1: match dimensions to display size
A 4000-pixel image displayed at 400 pixels wide transfers bytes for nothing. Rule of thumb: make the file as large as — but no larger than — the biggest size it is actually displayed at (up to 2× for Retina screens).
Step 2: choose the right format
- JPEG: classic photos; works everywhere.
- PNG: sharp edges, text or transparency; usually heavy for photos.
- WebP: usually smaller than JPEG and PNG at the same quality, and supports transparency. All modern browsers support it (what is WebP?).
- SVG: logos and simple icons; vector, almost weightless.
Step 3: lower quality gradually
100% quality is rarely needed. For lossy formats like JPEG and WebP, the 75-85 range usually looks nearly identical while cutting file size dramatically. The best method: try a few values and compare with your own eyes — there is no magic number for every image.
Step 4: ship multiple sizes (srcset)
Instead of one big file, make several versions (for example 480, 768, 1280) and let the browser pick with srcset and sizes. A phone doesn't need the desktop version:
<img src="hero-1280.webp"
srcset="hero-768.webp 768w, hero-1280.webp 1280w"
sizes="(min-width:1024px) 960px, 100vw"
width="1280" height="580" alt="Describe the image">
Step 5: set width/height and lazy-load
- Write
widthandheightso the page doesn't shift while loading (CLS). - Make below-the-fold images
loading="lazy". - Only the main hero image (the LCP element) should load early, with priority.
A real example
On this site, after converting to WebP, the founder photo became about 13 KB and the NØX hero image ships in three sizes between 19 and 69 KB — all from a 1900-pixel screenshot.
Which tools?
For a few images, the image tool I built does everything in the browser and never uploads your files: format, quality and resize. For big batches, a script (Python with Pillow, or Node with sharp) is better.
Checklist
Right dimensions; WebP (or JPEG); quality around 75-85; multiple sizes with srcset; width/height set; lazy-load everything except the hero image.