The quality ladder: what each step actually costs
Question: As you push the quality slider from 50 to 100, how fast does the file grow for JPEG and for WebP — and is the top of the slider ever worth it?
Findings
- WebP was smaller than JPEG at every step of the ladder on both images — by 57% at quality 50 on the texture image, and by roughly 30–40% throughout on the text page.
- JPEG quality 100 is a trap. On the texture image it produced 2.40 MB against 943 KB at quality 95 — 2.5x the bytes for the last sliver of a lossy encode. The curve is gentle up to 90 and then turns sharply.
- WebP quality 100 does the opposite: it got dramatically SMALLER, not larger — 68 KB against 304 KB at quality 95 on the texture image, and 53 KB against 393 KB on the text page.
- We verified why rather than guessing: at exactly quality 1.0 this encoder switches WebP into LOSSLESS mode. Decoding the quality-100 output and comparing it against the source gave a maximum per-channel difference of 0 — pixel-identical — while quality 95 and even 99 differed by up to 96 levels. On structured content, lossless WebP beats a high-quality lossy encode on size as well as fidelity.
- Practical consequence for our tools: dragging the quality slider to 100 on a WebP conversion is not "maximum lossy", it is a different, lossless codec mode — often both perfect and smaller. Dragging a JPEG conversion to 100 just wastes bytes.
The data
| Image | Format | Quality | Bytes |
|---|---|---|---|
| photo-detail | jpeg | 50 | 316,293 |
| photo-detail | webp | 50 | 136,632 |
| photo-detail | jpeg | 60 | 357,510 |
| photo-detail | webp | 60 | 149,314 |
| photo-detail | jpeg | 70 | 419,089 |
| photo-detail | webp | 70 | 164,700 |
| photo-detail | jpeg | 80 | 513,746 |
| photo-detail | webp | 80 | 196,758 |
| photo-detail | jpeg | 90 | 714,995 |
| photo-detail | webp | 90 | 262,414 |
| photo-detail | jpeg | 95 | 943,252 |
| photo-detail | webp | 95 | 304,044 |
| photo-detail | jpeg | 100 | 2,403,299 |
| photo-detail | webp | 100 | 67,860 |
| text-dense | jpeg | 50 | 305,432 |
| text-dense | webp | 50 | 207,490 |
| text-dense | jpeg | 60 | 342,183 |
| text-dense | webp | 60 | 220,168 |
| text-dense | jpeg | 70 | 388,860 |
| text-dense | webp | 70 | 232,670 |
| text-dense | jpeg | 80 | 451,592 |
| text-dense | webp | 80 | 266,366 |
| text-dense | jpeg | 90 | 558,535 |
| text-dense | webp | 90 | 332,522 |
| text-dense | jpeg | 95 | 664,960 |
| text-dense | webp | 95 | 392,918 |
| text-dense | jpeg | 100 | 839,807 |
| text-dense | webp | 100 | 52,596 |
⬇ Download raw data (CSV) ⬇ Download report (JSON)
Method
- Generate dataset B deterministically — a different, larger dataset from the format-comparison study, chosen for the two hardest compression cases (high-frequency texture and dense small text).
- Encode each image to JPEG and WebP at each quality step and record exact bytes.
- For the quality-100 result, verify losslessness directly: decode the output, compare it pixel-by-pixel against the source, and record the maximum per-channel difference.
- Download /labs/run-image-labs.js and paste its contents into the DevTools console.
Limitations
- Synthetic sources chosen as worst cases; ordinary photos produce gentler curves.
- Chrome 148 only — the quality-100 behaviour below is this encoder's policy, not a property of the WebP format itself, and other browsers may differ.
- Byte size plus an exact losslessness check; no perceptual metric is claimed for the intermediate steps.
Takeaway
For JPEG, stop at 90 — beyond that you pay a great deal for nothing anyone can see. For WebP, either sit in the 70–85 range for real savings, or go all the way to 100 for a pixel-perfect lossless file that, on flat or structured images, can be smaller than the lossy versions. The middle of the WebP slider is the only place the usual size/quality trade-off applies.
Advertisements
← All Labs reports · standards in the testing methodology