Compression gzip brotli
Enable Brotli/gzip for text assets, pick quality levels, and verify Content-Encoding in production.
- performance
- compression
- brotli
- gzip
- cdn
Text assets (HTML, CSS, JS, SVG, JSON) compress extremely well. Serving them uncompressed is free latency on every visit. Brotli (br) usually beats gzip for static text at rest; gzip remains a universal fallback.
Docs: web.dev codex compress (related ecosystem), MDN Content-Encoding, Can I use Brotli.
What to compress
| Compress | Don’t bother (already compressed) |
|---|---|
| JS, CSS, HTML, SVG, JSON, XML | JPEG, PNG, WebP, AVIF, mp4, woff2 |
Double-compressing WOFF2/images wastes CPU and can grow size.
Headers
Content-Encoding: br
Vary: Accept-Encoding
Content-Type: application/javascript; charset=utf-8
Clients send Accept-Encoding: gzip, deflate, br. Origin/CDN picks best mutual encoding.
Brotli vs gzip
| Brotli | gzip | |
|---|---|---|
| Ratio on JS/CSS | Often better | Good |
| CPU at high quality | Higher | Lower |
| Support | All modern browsers | Universal |
Static precompression at build (.js.br, .js.gz) with high Brotli quality (11) is ideal for fingerprinted assets. Dynamic compression at the edge uses lower levels for TTFB.
CDN / server sketches
# conceptual
gzip on;
brotli on;
brotli_types text/css application/javascript application/json image/svg+xml;
Prefer CDN features that store compressed variants next to objects.
Verify
Network panel → Response headers content-encoding: br. Size column: transferred vs resource size. If transferred ≈ uncompressed, compression isn’t applied.
Level selection
| Asset type | Advice |
|---|---|
| Fingerprinted static | Precompress max quality offline |
| SSR HTML | Medium level — balance TTFB vs size |
| Streaming | Careful with buffer delays |
Security note
Compression + secrets in responses can interact with BREACH-class attacks on particular setups. Don’t reflect secrets next to attacker-controlled bodies over compressed TLS without understanding the threat — mostly a backend concern, but know it exists.
Interview out-loud
“Compress text with Brotli preferably and gzip fallback; skip already-compressed media and woff2. Precompress static hashed assets, set Vary: Accept-Encoding, and verify Content-Encoding in Network panel.”
How this shows up in interviews
Be ready to define the metric or technique in one sentence, name one measurement approach (DevTools panel, web-vitals, or headers), and cite a concrete fix you would try first. Walk through a before/after: what the waterfall or flame chart showed, what you changed, and which percentile moved. Mention a tradeoff (complexity, caching correctness, or third-party business constraints) so the answer doesn’t sound like a blog checklist.
Production guardrails
Ship behind a flag when the change is risky, watch field p75 for the affected template for at least a few days, and keep a rollback path. Pair lab verification (throttled Performance/Network) with RUM so you don’t celebrate a Lighthouse-only win. Document the owner of any ongoing budget or third-party exception.
Related
- Caching static assets fingerprinting
- HTTP caching headers
- JavaScript bundle budget
- TTFB and Server-Timing
Further depth
Teams often under-invest in this topic until an incident or CWV regression. Schedule a one-hour drill: reproduce the failure mode in DevTools, list the top three mitigations for your stack, and file tickets with owners. Revisit after the next major feature that touches networking, rendering, auth, or third parties — those are the moments regressions land. Keep primary documentation links in the runbook so on-call is not searching chat history at 2am.
Concrete artifacts to leave behind: a short architecture note, a CI assertion or header snapshot, and a dashboard panel (lab or field) that would have caught the last bug. Teaching the rest of the team the mental model matters as much as the one-line fix.
Further reading
Related guides
- Caching Static Assets FingerprintingContent-hash filenames, long-cache headers, HTML revalidation, and CDN invalidation without stuck users.
- HTTP/2 and HTTP/3 for FrontendWhat H2/H3 change for waterfalls, prioritization, and why domain sharding died — frontend-relevant bits only.
- TTFB and Server TimingDiagnose Time to First Byte with Navigation Timing and break down backend phases via Server-Timing.
- Avoiding Layout ThrashingStop forced sync layout loops: batch DOM reads and writes, use rAF, and fix janky measurement code.
- CLS Optimization TacticsFix cumulative layout shift: dimensions, font metrics, reserved slots, and stable late-loading UI.