How Image Compression Actually Works: Lossy vs Lossless, WebP, and AVIF
When you upload a photo to a website, it gets smaller. Sometimes it looks identical; sometimes you can see blocky artifacts around text and edges. The difference is lossy versus lossless compression, and understanding the distinction is the difference between shipping a 200 KB image and a 2 MB one with no visible quality loss.
Image compression is not magic. It is mathematics and human perception working together. JPEG, WebP, and AVIF each use variations of the same core techniques: color space conversion, frequency transforms, quantization, and entropy coding. The formats that win do so because they make better bets about which visual details you will not notice missing.
Let us walk through how each stage works, how modern formats improve on the original JPEG standard, and how you can use all of this in your browser today.
The JPEG Pipeline: A Master Class in Perceptual Coding
JPEG was published in 1992 (ITU-T T.81, ISO/IEC 10918-1). It is over thirty years old, and it remains the most widely used image format on the web. The secret to its longevity is a pipeline that maps neatly onto the human visual system.
Step 1: Color Space Conversion (RGB to YCbCr)
Your eyes are more sensitive to brightness (luma) than to color (chroma). JPEG exploits this by converting the image from RGB to YCbCr, where the Y channel carries brightness information and the Cb and Cr channels carry blue-difference and red-difference chroma components.
This conversion is lossless in theory (it is a linear matrix multiply), but it sets up the next step.
Step 2: Chroma Subsampling
Because the human eye resolves color at a lower spatial frequency than brightness, JPEG can discard half or three-quarters of the chroma data without a visible difference. The 4:2:0 scheme records every Y pixel but only one Cb and one Cr sample for every 2x2 block of pixels. That is a 50% data reduction before any compression algorithm touches the image.
Chroma subsampling is your first encounter with a key principle: image compression is about discarding what people cannot see, not about shrinking what is there.
Step 3: 8x8 Block DCT Transform
JPEG divides the image into 8x8 pixel blocks and applies the Discrete Cosine Transform (DCT) to each block. The DCT converts spatial data (pixel brightness values) into frequency coefficients. The top-left coefficient represents the average brightness (DC component); the ones further from the top-left represent increasingly high-frequency details.
In a typical photograph, most of the visual energy concentrates in the low-frequency components. High-frequency details (sharp edges, fine texture) contribute less to overall appearance. The DCT does not compress anything by itself. It just rearranges the data so the next step can discard the unimportant parts.
Step 4: Quantization
This is where the actual compression happens. Each 8x8 DCT coefficient block is divided by a quantization table and rounded to the nearest integer. High-frequency coefficients (bottom-right of the block) get divided by larger numbers and often round to zero, producing long runs of zeros that the next stage can encode efficiently.
The quantization table is the quality knob. A JPEG at quality 85 uses small divisors across the table, preserving most frequency data. At quality 20, the divisors are large, and many coefficients round to zero, producing the characteristic blocky JPEG artifacts around sharp edges.
Step 5: Entropy Coding (Huffman or Arithmetic)
After quantization, each block contains many zero coefficients in the high-frequency zone. The encoder scans the block in a zig-zag pattern (top-left to bottom-right) that groups the zeros into runs. It then applies Huffman coding (or arithmetic coding for the optional lossless JPEG mode) to represent frequent coefficient patterns with short codes and rare ones with longer codes.
Run-length encoding followed by Huffman coding typically reduces the quantized DCT data by another 30-50%.
WebP: VP8 Intra-Frame Compression
Google introduced WebP in 2010 as a replacement for JPEG that could cut file sizes by 25-35% at equivalent quality. WebP uses the same basic pipeline (color conversion, transform, quantization, entropy coding), but with several improvements over JPEG.
Block-Based Prediction
Instead of applying DCT to every 8x8 block independently (the JPEG approach), WebP's VP8 codec uses intra-frame prediction. It looks at neighboring blocks (above and to the left) and predicts what the current block should contain. It then encodes only the residual, the difference between the prediction and the actual block. On smooth gradients and uniform areas, the prediction is nearly perfect, so the residual is very small.
This is the same technique used in H.264 video encoding. In fact, VP8 borrows heavily from H.264's intra-frame coding tools.
Adaptive Block Sizes
WebP uses 4x4, 8x8, or 16x16 blocks depending on the content of the image. Larger blocks work well on uniform regions (skies, walls), and smaller blocks handle detailed areas. JPEG is stuck with 8x8. This flexibility alone accounts for a measurable fraction of WebP's size advantage.
More Flexible Entropy Coding
WebP uses arithmetic coding for its entropy stage instead of Huffman coding. Arithmetic coding produces a more compact bitstream than Huffman for the same symbol probabilities. The improvement is typically 5-10% over Huffman, and it is essentially free in decoding cost on modern hardware.
Lossless WebP
WebP also supports a lossless mode (VP8L) that uses spatial prediction, a palette dictionary, and a different entropy coder. Lossless WebP typically beats PNG by 25-30% on screenshots and synthetic images, which makes it a strong alternative for UI assets.
AVIF: AV1 Intra-Frame Compression
AVIF (AV1 Image File Format) arrived in 2019, based on the AV1 video codec from the Alliance for Open Media. AVIF pushes compression efficiency further than WebP, typically matching WebP at 50% of the file size or surpassing JPEG at 50% of the size.
Larger Transform Blocks
Where JPEG uses 8x8 blocks and WebP uses up to 16x16, AVIF supports blocks up to 64x64. Larger transforms capture longer-range patterns in the image, which means fewer blocks to encode and less overhead. On high-resolution photographs, this alone can save 10-15% over WebP.
Multiple Transform Types
AVIF does not just use DCT. It also supports ADST (Asymmetric Discrete Sine Transform) and identity transforms, selecting the best one per block based on the residual characteristics. ADST is particularly effective on blocks that are not well modeled by DCT, such as blocks with strong directional edges.
Super-Resolution Rendering
AVIF includes a built-in upscaling tool in the decoder. The encoder can downscale the image before encoding (for example, encoding at half resolution) and signal the decoder to upscale it back during rendering. At low bitrates, this produces significantly better visual results than encoding a full-resolution image with heavy quantization.
HDR and Wide Color Gamut
AVIF supports 10-bit and 12-bit color depth, HDR metadata (PQ and HLG transfer functions), and wide color gamuts like BT.2020. JPEG is capped at 8-bit sRGB. If your audience includes HDR displays, AVIF is currently the only practical choice for the web.
Format Comparison
| Feature | JPEG | WebP | AVIF |
|---|---|---|---|
| Year introduced | 1992 | 2010 | 2019 |
| Block size | 8x8 | 4x4 to 16x16 | 4x4 to 64x64 |
| Transform | DCT | DCT + prediction | DCT, ADST, identity |
| Chroma subsampling | 4:4:4 to 4:2:0 | 4:4:4 to 4:2:0 | 4:4:4 to 4:2:0, plus 4:0:0 |
| Lossless mode | No (JPEG-LS separate) | Yes (VP8L) | Yes |
| HDR support | No | No | Yes (10/12-bit, PQ/HLG) |
| Browser support | Universal | 96%+ | 92%+ |
| Typical saving vs JPEG | baseline | 25-35% smaller | 50%+ smaller |
Browser-Based Image Compression with the Canvas API
You do not need a server or a WASM codec to compress images in the browser. The Canvas API lets you re-encode images with configurable quality using a few lines of JavaScript.
function compressImage(file, quality = 0.8, format = 'image/jpeg') {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
// Draw the image onto a canvas at its original size
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
// Export the canvas as a compressed image
canvas.toBlob(
(blob) => resolve(blob),
format,
quality
);
};
img.onerror = reject;
img.src = URL.createObjectURL(file);
});
}
// Usage: compress a 5 MB JPEG to quality 0.6
const photo = document.querySelector('input[type=file]').files[0];
compressImage(photo, 0.6).then((blob) => {
console.log(`${photo.size} B -> ${blob.size} B`);
});
The toBlob API lets you specify image/jpeg, image/webp, or image/png. At the time of writing, image/avif is not yet supported by Canvas in most browsers, though Chrome has an experimental flag.
Converting Between Formats
You can also use Canvas to convert between formats. This is how the Format Converter tool works: load an image onto a hidden canvas, then export it in the target format at your chosen quality. Everything runs in your browser. Your image file never touches a server.
File Size Benchmarks
Here are real benchmarks from a 1920x1080 photograph encoded in each format at roughly equivalent visual quality:
| Format | Quality | File Size | Saving vs JPEG |
|---|---|---|---|
| JPEG | 85 | 482 KB | baseline |
| WebP | 80 | 342 KB | 29% smaller |
| AVIF | 50 | 223 KB | 54% smaller |
| JPEG | 50 | 218 KB | 55% smaller (visible quality loss) |
The key insight: AVIF at quality 50 matches JPEG at quality 85 visually while cutting the file size by more than half. WebP splits the difference, offering a meaningful improvement with broader tooling support today.
WASM Codecs in the Browser
For advanced use cases beyond what the Canvas API offers, WASM-based codecs bring full encoder control to the browser. Libraries like libjpeg-turbo, libwebp, and libavif have been compiled to WebAssembly, giving JavaScript applications direct access to the same encoding libraries that server-side tools use.
The Image Compressor tool on this site uses a combination of Canvas API encoding and a WASM-based WebP encoder to give you fine-grained control over output quality, format selection, and file size targets. Everything happens client-side. Your images never leave your browser.
Which Format Should You Use?
The short answer is: serve multiple formats and let the browser pick. The <picture> element makes this straightforward:
<picture>
<source srcset="photo.avif" type="image/avif">
<source srcset="photo.webp" type="image/webp">
<img src="photo.jpg" alt="Your photo">
</picture>
Browsers that support AVIF get the smallest file. Browsers that support WebP but not AVIF (older Safari, some mobile browsers) get the middle option. Everything else falls back to JPEG. This pattern works today and covers 99.9% of your users.
For lossless use cases (screenshots, UI elements, diagrams), prefer WebP or AVIF over PNG. Lossless WebP typically achieves 25-30% smaller files than PNG, and lossless AVIF (where supported) can save another 10-15% on top.
For a deeper look at how browser-based image processing works under the hood, check out the browser image editing guide. It covers Canvas pixel manipulation, format detection, and fallback strategies in more detail.
Summary
Image compression is a series of deliberate trade-offs informed by the limits of human vision. JPEG established a pipeline (color conversion, chroma subsampling, DCT, quantization, entropy coding) that has been refined but not fundamentally replaced. WebP improved on JPEG by adding intra-frame prediction, adaptive block sizes, and better entropy coding. AVIF pushed further with larger transforms, multiple transform types, and native HDR support.
The format choice matters less than the decision to offer multiple options. Serve JPEG as a fallback, WebP as the baseline, and AVIF as the upgrade. Your users on fast connections get crisp images; your users on mobile networks get faster page loads. No one sees the artifacts unless they zoom in to pixel-peep, and at that point, the compromise has already paid for itself in bandwidth saved.
