Compression: gzip, Brotli, zstd

Play this lesson

Text repeats itself

Shard Garden's game code is 2.4 MB of JavaScript. Look inside and the same words appear thousands of times: function, shard, garden, return.

Compression rewrites data in fewer bytes by replacing repeats with short references to earlier copies. It is lossless: decompressing gives back exactly the original bytes, which code needs. One missing letter would break the game.

How the browser and server agree

The browser lists what it can decompress: Accept-Encoding: zstd, br, gzip. The server picks one, compresses the file and labels it: Content-Encoding: br.

It also sends Vary: Accept-Encoding. That tells caches the answer depends on that request header, so they keep a separate copy for each encoding and never hand a Brotli file to a browser that can only read gzip.

Read the headers

GET /game.4be1.js
Request:  Accept-Encoding: gzip Response:  Content-Encoding: ???  Vary: Accept-Encoding

An old browser only lists gzip. What should the server send?

  1. The file compressed with gzip
  2. The Brotli file anyway, because it is smaller
  3. The zstd file, because it is fastest
Show the answer

The file compressed with gzip

The server may only use an encoding the browser listed. A Brotli file sent to a browser that only reads gzip would arrive as unreadable bytes.

Three algorithms

True story: Brotli, the small bread

On 22 September 2015, Zoltan Szabadka of Google's Compression Team announced Brotli, a new compression format. Google's earlier compressor, Zopfli, squeezed files in the old gzip-compatible way. Brotli was a whole new format, and it reached 20 to 26% higher compression ratios than Zopfli while running roughly as fast as zlib's Deflate.

Like Zopfli, it was named after a Swiss bakery product: Brötli means "small bread" in Swiss German.

A new format only helps once browsers can read it, which is exactly what Accept-Encoding checks.

Source: Google Open Source Blog: Introducing Brotli (2015), opensource.googleblog.com

Quick check

Brotli and zstd are lossy: after decompressing, the file is slightly different from the original.

Show the answer

False

Both are lossless. The browser gets back exactly the original bytes, which is the only acceptable result for code.

Don't squeeze what's already squeezed

Images, audio and video are already compressed inside their own formats. MDN advises compressing everything except those: compressing them again gains almost nothing, and the overhead can even make the file bigger.

So Remy's server compresses JavaScript, CSS, HTML, JSON level files and SVG icons, and sends AVIF images and music files as they are.

Pick the files

Which files should Remy's server compress with Brotli or zstd?

  1. game.js, style.css and level-12.json
  2. key-art.avif and theme-music.ogg
  3. Every file, including the images and music
Show the answer

game.js, style.css and level-12.json

Text files shrink a lot. AVIF images and Ogg music are already compressed, so a second round wastes server time and can add bytes.

Levels: size or speed

Images need their own tricks

Compression shrinks our text. Our art is a different problem, because it is already compressed and because the GPU has to unpack it.

Bolt says: Next: AVIF, WebP and the texture formats that stay small even inside the GPU.

Fact-checked 11 October 2026