Website Spec
← Performance
Required

Compression (gzip, brotli, zstd)

Compress text responses with brotli where supported, gzip everywhere else. zstd is emerging. Don't compress already-compressed media.

What it is

HTTP content encoding compresses response bodies on the server and decompresses them in the browser. The client advertises supported algorithms in Accept-Encoding; the server picks one and announces it in Content-Encoding.

Request:
Accept-Encoding: br, gzip, zstd

Response:
Content-Encoding: br
Vary: Accept-Encoding

The common algorithms:

Why it matters

Text resources — HTML, CSS, JavaScript, JSON, SVG, XML — compress to 20–30% of their original size. On a 200KB JavaScript bundle, that is 140KB saved per request, multiplied by every user. Compression is one of the cheapest performance wins available, and a Lighthouse audit failure if missing.

How to implement

Compress all text. HTML, CSS, JS, JSON, SVG, XML, plain text, and most fonts (WOFF2 is already compressed; WOFF is not).

Negotiate via Accept-Encoding. Most servers and CDNs do this automatically. Configure them to prefer brotli, fall back to gzip:

Pre-compress static assets. For files that don't change (your bundled JS), compress at build time to maximum level (brotli quality 11, gzip level 9) and let the server serve the .br or .gz file directly. Runtime compression usually runs at level 5–6 for CPU reasons.

Set Vary: Accept-Encoding. Tells CDNs to keep a separate cache entry per encoding. Without it, gzip clients may receive a brotli body they can't decode.

Don't double-compress. Images (JPEG, PNG, WebP, AVIF), video, fonts (WOFF2), and zip files are already compressed. Re-encoding wastes CPU and often grows the file.

Common mistakes

Verification

Sources