Three server-side settings that cost nothing to change and are wrong on a surprising number of sites. None requires touching your application code, and together they usually beat any amount of front-end tuning.
Both shrink a file. Only one is usually missing, and it is the one with the larger effect.
Minification removes whitespace and shortens names inside the file; gzip or brotli compresses the bytes in transit. They stack, but compression does far more of the work on text, routinely cutting CSS and JavaScript by around two thirds or better, and it is a server setting rather than a build step. That is why an uncompressed but minified file is a worse outcome than a compressed but unminified one, and why the first thing to check is the Content-Encoding response header rather than the contents of your bundle.
Four settings, in the order they usually pay off.
Check for Content-Encoding: gzip or br on every CSS and JavaScript response. Missing it means sending several times more bytes than necessary on every single request.
The usual cause is a proxy or CDN in front of an origin that compresses correctly, where the front layer never had it enabled.
Without Cache-Control, a returning visitor re-downloads assets that have not changed. The first visit is unaffected, so this is invisible in most one-off tests.
Fingerprint filenames and cache them for a long period. Content-hashed names make a long max-age safe, because a change produces a new URL.
Worth doing and usually already handled by the build. Treat it as the smaller win that comes after compression, not before it.
If files are unminified in production, the more likely story is that a build step is not running at all, which is worth knowing on its own.
Each file is a request with its own overhead. HTTP/2 made this much cheaper than it was, so the old advice to concatenate everything no longer applies automatically.
It still matters at the extremes. Forty small stylesheets is worth consolidating; four is not worth touching.
They are response headers, so they live outside the code most teams look at.
A developer optimising bundle size is working in the build. Compression and caching are configured in nginx, a CDN dashboard, or a hosting panel, often by someone else and often years earlier. That separation is why a team can spend a sprint on code splitting while every asset ships uncompressed. It also explains the common pattern where one part of a site is configured correctly and another is not: static files on a CDN get compression and caching, while assets served directly from the application do not, and nothing surfaces the difference.
Cheapest and safest first.
Enable compression for text content types on every layer that serves them, including the CDN or proxy. Then set long cache lifetimes on fingerprinted assets and short ones on HTML, which should not be cached aggressively because it is the file that points at everything else. Then check minification is actually running in production. Only then consider consolidating files, and only if the count is genuinely high.
All of this sits underneath the work of removing render-blocking resources: compression makes each blocking file arrive faster, while deferring stops it blocking at all. Doing both is what moves the number, and delivery is the half you can fix without touching the page.
Open your browser's network panel, reload the page, and check the response headers on any CSS or JS file for Content-Encoding: gzip or br. If the header is absent, that file is being sent uncompressed.
Prefer brotli where your server or CDN supports it: it generally compresses text smaller than gzip at an equivalent level, and every modern browser negotiates it. Keep gzip as the fallback for the rare client that does not. Most servers can serve both and let the browser pick.
It tells the browser how long it can reuse a file without asking the server again. A long max-age on a fingerprinted filename means a returning visitor skips the network for that file entirely until it changes. Without it, every visit re-downloads assets that never changed.
An ETag lets the server answer with a cheap 304 instead of resending a file that has not changed, which helps for assets you cannot fingerprint in the URL. A fingerprinted filename with a long Cache-Control is stronger, because the browser skips the request entirely rather than shortcutting it. Use both where you can.
No. A CDN moves cached copies closer to the visitor, which cuts latency, but whether those copies are compressed and how long they are cached is still governed by the headers your origin or CDN configuration sends. A site can sit behind a CDN and still ship every asset uncompressed if compression was never switched on.
Yes, as the smaller of the two wins. Compression removes most of the redundancy in text already, so minifying on top closes a narrower gap. Do both, and if production is serving unminified files at all, treat it as a sign your build step may not be running the way you expect.
Free to start. Reports CSS and JavaScript served without compression, missing cache headers, unminified files, and pages loading too many separate assets.
Start my free audit