Every byte you ship costs time, and time costs revenue. Before your online store's HTML, CSS, and JavaScript reach the browser, they can be shrunk to a fraction of their original size, provided the server compresses cleanly. This is where Brotli comes in, the more modern successor to Gzip: Brotli compresses HTML about 21%, CSS 17%, and JavaScript 14% better than Gzip (DebugBear). Yet 61% of origin servers still serve their responses in Gzip, only 39% in Brotli (HTTP Archive). And 56% of all HTML responses plus 18% of JavaScript and CSS resources are not compressed at all (HTTP Archive). This guide explains how Brotli and Gzip work, how to ship text assets through minification and correct server configuration, and why the right compression level determines load time and performance.
Why Asset Compression Drives Revenue
Text-based resources are about as compressible as it gets. An average home page today carries 22 kB of HTML, 82 kB of CSS, and 697 kB of JavaScript (each median, HTTP Archive 2025), and that last figure has been growing for years. The median page now weighs 2.86 MB on desktop and 2.56 MB on mobile (HTTP Archive 2025). A large share of that is text that can be shrunk aggressively without losing a single pixel. Images dominate the weight at around 1,059 kB per home page (HTTP Archive), but they are already binary-compressed. The real, often untapped reserve lies in the text portion.
The business value is directly measurable. According to the Milliseconds Make Millions study by Google and Deloitte, every 0.1-second improvement in load time increases retail conversions by 8.4% and average order value by 9.2% (Google/Deloitte). Amazon calculated that every additional 100 ms of latency costs around 1% of revenue (Conductor). An analysis of over 100 million page views found that pages loading in one second convert at 3.05%, at two seconds only 1.68%, and at five seconds 1.08% (Portent). Compression is one of the few levers you can pull across every page at once, with no design change and no risk.
The appeal of asset compression lies in its reach. Unlike optimizing a single template, correct server configuration affects every HTML page, every stylesheet, and every script file at once. It is a classic quick win: high impact for little effort and with no visible change to the interface. For online stores whose page weight grows with every new feature, tracking script, and third-party embed, this is a durable lever against creeping performance decay.
Brotli compresses HTML 21%, CSS 17%, and JS 14% better than Gzip (DebugBear), and Akamai measures a median saving of 82% with Brotli versus 78% with Gzip (DebugBear). With a JavaScript median of 697 kB per home page (HTTP Archive), that means noticeably fewer bytes transferred, at exactly the touchpoint where 100 ms decides over 1% of revenue (Conductor).
How HTTP Compression Works
HTTP compression is a negotiation between browser and server. In the request, the browser sends an Accept-Encoding header listing the methods it supports, such as gzip, br, zstd. The server picks one, compresses the response, and labels it with Content-Encoding. The browser decompresses it before processing. For users the process is invisible, only the load time gets shorter. This negotiation happens on every single request, which is why consistent server configuration matters so much: it is not enough for the HTML to arrive compressed if the JavaScript it loads stays uncompressed.
One quirk of modern browsers matters: Chrome, Firefox, Edge, and Safari advertise Accept-Encoding: br only over HTTPS. Over plain HTTP they fall back to Gzip, even when both sides support Brotli. Brotli is effectively tied to TLS, which is no problem in practice since virtually every store runs over HTTPS. Around 97% of users browse with a Brotli-capable browser (caniuse); Brotli has been understood since Chrome 50, Firefox 44, Edge 15, and Safari 11. There is therefore hardly an argument left for holding Brotli back on compatibility grounds, as long as Gzip remains configured as a fallback.
It also matters whether compression happens while a request is being served or whether already-compressed files are delivered. With on-the-fly compression, the compressed response is created fresh per request, which costs CPU time. With precompression, the file already exists as a .br or .gz variant and is simply handed out. This distinction is the key to choosing the right compression level, which the section on levels covers in detail.
Already-compressed formats such as JPEG, PNG, WebP, MP4, or WOFF2 fonts gain nothing from additional text compression, and may even grow slightly. Compress text-based MIME types specifically: text/html, text/css, application/javascript, application/json, image/svg+xml, and application/xml. Lighthouse flags a response only above 1.4 KiB and only when more than 10% savings are possible.
Brotli vs. Gzip: The Direct Comparison
Gzip is based on the DEFLATE algorithm and has been established since the 1990s. Brotli was developed by Google in 2015 and brings one decisive advantage: a predefined dictionary of more than 13,000 common web strings, including typical HTML tags, CSS properties, and JavaScript keywords. As a result, Brotli recognizes recurring patterns in web code better and achieves higher compression ratios, especially for small text files where Gzip performs worse without prior knowledge, because no statistical patterns have built up yet.
In Akamai's benchmark, the median saving was 82% with Brotli versus 78% with Gzip (DebugBear). Per file type, Brotli is about 21% better for HTML, 17% for CSS, and 14% for JavaScript (DebugBear). In one real-world test, DebugBear compressed a 173 kB JavaScript library to 61 kB with Gzip but only 52 kB with Brotli, around 15% smaller than Gzip (DebugBear). The difference sounds small but adds up across hundreds of requests per page and millions of page views. For a mid-sized shop home page with the media mix above, switching from Gzip to Brotli can save several dozen kilobytes per page view with no other changes.
| Criterion | Gzip | Brotli |
|---|---|---|
| Year introduced | 1992 (DEFLATE) | 2015 (Google) |
| Compression levels | 1-9 | 0-11 |
| HTML saving vs. Gzip | baseline | approx. +21% (DebugBear) |
| CSS saving vs. Gzip | baseline | approx. +17% (DebugBear) |
| Predefined dictionary | No | Yes (~13,000 entries) |
| Browser support | practically everywhere | approx. 97% (caniuse) |
| Top level on-the-fly | practical | static assets only |
On the horizon is Zstandard (zstd), increasingly used by CDNs: they now serve 12% of requests in zstd, 46% in Brotli, and 42% in Gzip (HTTP Archive). zstd offers a compression level similar to Brotli at higher speed, making it especially interesting for dynamic content. Origin servers, however, lag this trend: they still serve 61% in Gzip and only 39% in Brotli (HTTP Archive). For most stores, the combination of Brotli for static assets and Gzip as fallback therefore remains the pragmatic standard, while zstd is an option for the future.
Choosing the Right Compression Level
The level determines the trade-off between compression ratio and compute time. Brotli has levels 0 to 11, Gzip has levels 1 to 9. The highest Brotli levels produce the smallest files but are expensive: in Cloudflare's benchmark on dynamic web content, Brotli compressed at around 8.8 MB/s on level 9 but only about 0.5 MB/s on level 10, roughly seventeen times slower (Cloudflare). Level 4, by contrast, reached around 51 MB/s and stayed faster than zlib at levels 8 and 9 at a comparable compression ratio (Cloudflare). The decisive distinction is therefore between static and dynamic content, because only with static assets does the compute cost fall once rather than on every page view.
Static assets: Brotli 11
CSS, JS, and font-CSS files rarely change between deployments. They can be precompressed once at build time with Brotli level 11. The compute cost falls only at deploy, while the browser still decompresses extremely fast (Cloudflare).
Dynamic HTML: Brotli 4-5
HTML generated fresh on every request should be compressed on the fly at a medium level (Brotli 4-5 or Gzip 6). Cloudflare uses a low Brotli level by default for dynamic content, because level 11 would tie up too much CPU here (Cloudflare).
A proven strategy is precompression: at build time, a .br and a .gz variant are created alongside every .js and .css file. The web server then serves the prepared file without recompressing per request. This gives you the maximum Brotli ratio with zero runtime cost, a principle our hosting also uses for static shop assets. For dynamic responses such as category and detail pages, on-the-fly compression at a moderate level remains the right approach, because the HTML there depends on catalog, login status, and cart and cannot sensibly be generated in advance.
The effect of the level choice is measurable but not linear. Between Brotli 4 and Brotli 11, typical web code often gains only a few additional percentage points of saving, while compute time rises by an order of magnitude. That is precisely why the high level only makes sense where it is free, namely with static, precompressed files. Compressing dynamic HTML at level 11 by mistake risks higher response times under load, the exact opposite of the desired effect.
# Serve static, precompressed Brotli files
brotli_static on;
# On-the-fly Brotli for dynamic HTML (moderate level)
brotli on;
brotli_comp_level 5;
brotli_types text/html text/css application/javascript application/json image/svg+xml application/xml font/ttf;
# Gzip fallback for older clients
gzip on;
gzip_comp_level 6;
gzip_vary on;
gzip_types text/html text/css application/javascript application/json image/svg+xml application/xml;Minification: Fewer Bytes Before Compression
Compression and minification are two distinct steps that complement each other. Minification removes everything superfluous from the source before delivery: comments, line breaks, redundant whitespace, and sometimes long variable names. The result stays functionally identical but is significantly smaller. Minification typically reduces JavaScript by 30 to 60% and CSS by 20 to 40% (DebugBear). In modern build pipelines this happens automatically, often combined with tree shaking, which removes unused code entirely.
The real effect comes from the interplay. An unminified 88 kB file shrinks to 26.5 kB through minification alone, a 70% reduction (DebugBear). Combine minification with Brotli and you reach an overall size reduction of around 90% (DebugBear). Order matters: minify first, then compress, because the compressor works more efficiently on already-minified code, since less redundant structure remains that it would have to strip anyway.
- Minify JavaScript - remove comments and whitespace, shorten variables, eliminate dead code (tree shaking) in the build process
- Minify CSS - remove unused rules, reduce whitespace, use shorthand notation
- Minify HTML - on static pages remove whitespace and comments, test carefully on dynamic ones
- Optimize SVG - strip metadata and unnecessary path data, since SVG is compressed as text
- Keep JSON APIs lean - do not ship pretty-print formatting in production responses
- Use code splitting - load only the JavaScript the given page actually needs
Minification and compression address different kinds of redundancy. Minification removes human-readable structure, compression removes statistical repetition. Only together do they reach their maximum: around 90% reduction with minification plus Brotli (DebugBear). Using only one of the two leaves transfer volume on the table.
Server Configuration and Common Mistakes
Despite the clear advantages, much potential goes unused. 62% of websites pass the Lighthouse Enable text compression audit, but around 21% score below 40 (HTTP Archive). Specifically, 56% of HTML responses plus 18% of JavaScript and CSS resources are not compressed at all (HTTP Archive). Among the affected pages, 82% could cut their page weight by up to 1 MB (HTTP Archive), through correctly configured compression alone. That is a substantial reserve that can be unlocked with no new content, no redesign, and no risk to functionality.
The most common causes are technical and quickly fixed. Often the Brotli module is simply not enabled, or the list of compressed MIME types is incomplete, so that JSON APIs or SVGs go out uncompressed. A classic mistake is also an upstream reverse proxy or web application firewall that decompresses compressed responses and passes them on uncompressed. In such cases compression is correctly configured at the origin but never reaches the browser, a problem only revealed by inspecting the header actually delivered.
- Enable the Brotli and Gzip modules and configure both in parallel, Brotli first, Gzip as fallback
- List MIME types completely - include HTML, CSS, JS, JSON, SVG, and XML
- Set
Vary: Accept-Encodingso caches and CDNs serve the right variant - Precompress static assets (
.br/.gz) and serve them withbrotli_static/gzip_static - Separate levels - Brotli 11 for static, Brotli 4-5 or Gzip 6 for dynamic
- Verify the result with Lighthouse, WebPageTest, or the
Content-Encodingheader in DevTools
Without a correct Vary: Accept-Encoding header, you risk a CDN or browser cache serving a Gzip variant to a Brotli-capable client, or conversely a Brotli file to an old client that cannot understand it. After every change, check the Content-Encoding header in browser DevTools to confirm that br actually arrives. A well-designed CDN strategy resolves this negotiation cleanly at the edge.
Compression in the Bigger Performance Picture
Compression works best as part of an end-to-end performance strategy. It reduces transfer time, the interval between the request and the complete receipt of a resource. That feeds directly into Largest Contentful Paint and time to interactivity, both core web vitals. The effect is especially noticeable on mobile connections with limited bandwidth, where every saved kilobyte makes a measurable difference in perceived load time.
Compression does not replace the other optimization layers, it complements them. It combines well with server-side caching such as Redis, which lowers backend response time, with modern protocol optimization through HTTP/3 and QUIC, which speeds up connection setup, and with holistic Shopware performance optimization. Compute loads can also be offloaded to serverless edge functions, while a clean webhook architecture decouples data-intensive processes and keeps the response time of the actual shop pages stable.
For online stores with a growing catalog, many campaigns, and an increasing share of JavaScript, clean asset compression is therefore not optional polish but basic equipment. It is the base layer on which all further optimizations build, and after the one-time setup it costs practically nothing. As an agency in Lower Saxony focused on hosting and maintenance, we configure Brotli and Gzip server-side, establish precompression in the build, and interlock compression with caching, protocol, and frontend optimization, so that every byte you ship counts.
This article draws on data from: DebugBear (Brotli vs. Gzip compression ratios, Akamai benchmark, minification and combined reduction figures), HTTP Archive Web Almanac 2025 (Page Weight, Compression, CDN chapters and Lighthouse audit data), Google and Deloitte (Milliseconds Make Millions, conversion and AOV impact), Conductor (Amazon 100 ms study), Portent (load time and conversion rate), Cloudflare (compression levels, speed of dynamic Brotli compression), and caniuse (browser support for Brotli). The figures cited may vary depending on content, server configuration, and network.
Frequently Asked Questions About Brotli and Asset Compression
Gzip is based on the DEFLATE algorithm from 1992; Brotli was developed by Google in 2015 and uses a predefined dictionary of common web strings. As a result, Brotli compresses text-based assets more strongly, typically around 21% for HTML, 17% for CSS, and 14% for JavaScript (DebugBear). Gzip remains important as a broadly supported fallback.
Usually both: Brotli first for the roughly 97% of users on a supporting browser (caniuse), and Gzip as a fallback. Most web servers can be configured to automatically serve the right variant per request based on the Accept-Encoding header.
It depends on the content type. Static assets such as CSS and JavaScript can be precompressed once at build time with level 11, since the compute cost falls only at deploy. Dynamic HTML should be compressed on the fly at a medium level (around Brotli 4-5), because the highest levels typically compress more than ten times slower than level 9 (Cloudflare).
No, the two complement each other. Minification removes comments and whitespace and typically reduces JavaScript by 30 to 60% (DebugBear); compression additionally removes statistical repetition. Together, minification and Brotli typically reach around 90% size reduction (DebugBear).
Only text-based resources benefit: HTML, CSS, JavaScript, JSON, SVG, and XML. Already-compressed formats such as JPEG, PNG, WebP, MP4, or WOFF2 fonts should be excluded, since additional compression brings no benefit there and can slightly enlarge the files.
The simplest way is through browser DevTools: in the network tab, the Content-Encoding header shows per resource whether br (Brotli) or gzip arrives. In addition, tools such as Lighthouse with the Enable text compression audit or WebPageTest reveal whether resources are being served uncompressed.