Text Compression
Enable Brotli or Gzip on your server to shrink HTML, CSS, and JS by 60–80%.
Metrics
This technique can move up to 67% of LCP's share of the Lighthouse score.
This technique does not move TBT.
This technique does not move CLS.
This technique can move up to 67% of FCP's share of the Lighthouse score.
This technique can move up to 67% of SI's share of the Lighthouse score.
This technique does not move TTFB.
Overview
Text-based resources — HTML, CSS, JavaScript, JSON, SVG — compress 60–85% under Brotli and 55–75% under Gzip because source code and markup contain a huge proportion of repeated tokens. A 120 KB minified JavaScript file becomes 35 KB over the wire. Compression happens once on the server; decompression is near-instant on modern CPUs. It is the simplest high-ROI optimisation available at the server layer.
Impact grade, A+ to D: how much of the Lighthouse score this technique can move. Unaffected: TBT, CLS, TTFB.
The Problem
Without compression, every text resource transfers at its full uncompressed size. A typical WordPress page may load 300–600 KB of JavaScript and 80–200 KB of CSS. At 10 Mbps — a common real-world mobile connection — that adds 300–600 ms of transfer time before any byte can be parsed. Lighthouse reports ‘Enable text compression’ when it detects any text resource served without a Content-Encoding header.
Performance Impact
LCP
100–400ms
HTML and CSS needed to lay out the LCP element transfer sooner
FCP
100–500ms
render-blocking CSS and JS reach the parser faster
SI
100–400ms
all visible content painted sooner across the viewport
Risk: Negligible
lossless — decompressed content is byte-for-byte identical
How it works
01
Brotli vs Gzip
Brotli (br) compresses 15–25% better than Gzip for text and is supported by all modern browsers. Enable Brotli first with Gzip as a fallback for older clients. Both are lossless — decompressed content is identical to the original.
02
Enable in the web server
Nginx: add
brotli on;(ngx_brotli module) andgzip on;withgzip_types text/html text/css application/javascript. Apache: enablemod_deflateand optionallymod_brotli. Managed hosts often enable Gzip by default; check response headers to confirm.03
Pre-compress static assets
For assets that do not change between deployments — JS bundles, CSS files — generate
.brand.gzfiles at build time. Serve the pre-compressed file directly; the CPU cost is paid once at build rather than on every request.04
Verify with DevTools
Open Network tab, click any text resource, and check the Response Headers panel. Look for
Content-Encoding: brorContent-Encoding: gzip. Compare the Size and Transferred columns — a large gap means compression is working.
Limitations
- Compression increases CPU usage on the server for dynamically generated HTML — use caching alongside compression to avoid per-request cost.
- Already-compressed formats (JPEG, PNG, WebP, AVIF, WOFF2) do not benefit from additional compression — only apply to text types.
- Some CDNs re-compress responses — verify that the CDN is not stripping the Content-Encoding header from origin responses.
Common Mistakes
Enabling compression but forgetting Vary: Accept-Encoding
Without Vary: Accept-Encoding, a reverse proxy or CDN may cache the compressed response and serve it to a client that cannot decompress it. Nginx and Apache set this header automatically when compression is enabled via their modules.
Compressing binary image files
JPEG, PNG, WebP, and AVIF are already compressed. Adding Gzip or Brotli to these types wastes CPU and can slightly increase file size. Restrict compression to text/* and application/javascript types.
Need help applying this to your site?
Targeted fixes, not guesswork. We identify which techniques move the needle for your specific WordPress stack.
Start an Engagement