A number between 0 and 1

When an image is saved as JPG or WebP, the code hands the Canvas API a single quality value — a number between 0 and 1:

canvas.toBlob(blob => { ... }, "image/jpeg", 0.8);

That 0.8 is all that separates a razor-sharp 4 MB image from a mushy 200 KB one. The slider in the compression tool sets exactly this value. But what actually happens inside the image?

What "quality" means technically

JPG (and lossy WebP) splits the image into small blocks and deliberately throws away image information the eye barely misses — the finest differences in brightness and color. The quality value controls how aggressively things get thrown away: at 1 almost everything is kept, at 0.3 the reduction is drastic. The more gets discarded, the smaller the file — and the more visible the typical JPEG artifacts: blockiness along edges, clouding in smooth areas.

The curve isn't linear — and that's the trick

The biggest aha moment while building the tool: the relationship between quality and file size is not uniform. The first steps down from 100 cost barely any visible quality but save an enormous amount:

  • 100 → 90: hardly a visible difference, but often already half the size.
  • 90 → 80: still barely perceptible, another substantial saving.
  • 80 → 60: this is where you start having to look more closely; for photos often still acceptable.
  • below 50: artifacts become obvious, and the saving per step gets smaller.

Put differently: the most expensive bytes in an image sit in those last few percent of quality that hardly anyone sees. That's exactly why compression works so well — you give up almost nothing visible and gain a lot.

300 × 250 — Rectangle
Cookie-Banner ausstehend

Why our default is 80, not 100

The slider deliberately starts at about 80% (0.8). That's no accident — it's the much-cited sweet spot: high enough that photos look practically lossless on screen, low enough that the file has already shrunk dramatically. If we preset 100, most users would get needlessly large files without ever seeing the difference. 80 is the honest default for "looks good, nicely small".

What matters, though, is that the slider is there: if you need to squeeze an image further (email limit, slow upload portal), you go down; if you have a detail-critical image (product photo with fine texture), you go up. The default is a good starting point, not a straitjacket.

Format changes the math

The same quality value means different things in different formats: WebP at 0.8 is usually smaller than JPG at 0.8, with a similar look. And for graphics with crisp text, a high JPG quality value is often the wrong answer — that's where lossless PNG belongs, where the quality slider plays no role at all. That's why the tool deliberately leaves the format choice open.

The lesson

What stuck with us from building this: a single, well-chosen default takes the hardest decision off most users' plates. Very few people want to think about compression curves — they want an image that looks good and is small. The art isn't in offering a thousand options, but in picking the right default and keeping the slider ready for the exceptions. In image compression, that default is called 80.

300 × 250 — Rectangle
Cookie-Banner ausstehend

Sources

MDN — toBlob() and the quality parameter · MDN — JPEG image format.