Fewer Bytes on the Wire: Brotli, Minification and a Year of Browser Cache
Cached pages are now stored pre-compressed with Brotli, JS and CSS bundles are minified according to what they actually are, and assetUrl() earns your assets a year of immutable browser cache without ever serving a stale bundle.
Brotli, computed once
Everything outside the API area is compressed - published site content and portal assets alike. The interesting part is where.
A cached page is not compressed per request. When the cache entry is written, Brotli and gzip variants are written alongside it, off-thread, at Brotli quality 11 - the slowest and smallest setting there is. Every later hit serves a file that is already compressed. The expensive setting gets paid once and reused, instead of a cheaper setting being paid on every single request.
Files below 1 KB or above 8 MB skip the variants and are handled by the compression middleware instead.
Your site's own API is deliberately left out. yoursite.com/API/orders runs #/API/orders.js, is forced to application/json, and is never cached - so compressing it would mean paying CPU on every call, and it would drop Content-Length from the API log.
Minification follows the real MIME type
Minification runs when a page is rendered, never on a cache hit, and only when caching is enabled and the response is actually going into the cache.
Which minifier runs is decided by what the content genuinely is:
Content | Without a minify block | With minify.enabled |
|---|---|---|
| Whitespace compression |
|
| Untouched |
|
JavaScript | Untouched |
|
JSON, XML, plain text | Untouched | Untouched |
Watch the
htmlflag. Inside aminifyblock,jsandcssdefault totruebuthtmldefaults tofalse. So{"minify": {"enabled": true}}turns JS and CSS minification on and HTML whitespace compression off - probably not what you meant. Set all three explicitly.
{
"cache": { "enabled": true },
"minify": { "enabled": true, "html": true, "js": true, "css": true }
} A bundle that the minifier cannot parse is served in its original form and the problem is logged. Half-minified JavaScript breaks a page; the original never does.
JS and CSS bundles are written as .hash files that declare their own MIME type, and are referenced without that extension:
// /assets/js/bundle.js.hash - referenced as /assets/js/bundle.js
docly.setMime("text/javascript"); They are cached, pre-compressed and minified on exactly the same terms as HTML.
A year of browser cache, without stale bundles
Server-side invalidation has never been the hard part - publishing bumps the site's timestamp. The browser is the hard part: the URL has not changed, so it has no reason to fetch anything.
assetUrl() stamps your own relative asset URLs with the site's last-modified time:
<script src="#assetUrl('/assets/js/bundle.js')#"></script>
<!-- -> /assets/js/bundle.js?v=20260714183000 --> External and protocol-relative URLs come back untouched - we don't know when someone else's CDN last changed.
The stamp is only half of it. The other half is the cache policy that recognises it:
Response | Cache-Control |
|---|---|
Versioned asset ( |
|
Other static files |
|
Public HTML without a version |
|
A versioned URL can be frozen for a year precisely because a new publish produces a new URL. And public HTML revalidates every time, so the moment you publish, visitors pick up the new ?v= references immediately. Docly answers those revalidations with a 304 and an empty body, so they cost almost nothing.
That combination - immutable assets behind a versioned URL, always-fresh HTML pointing at them - is exactly what Lighthouse's "efficient cache policy" audit is looking for.
Templates that build faster
One more thing landed on the same theme, further down in the runtime. A method call chain used to resolve its receiver more than once, and in a chain each link multiplied the work beneath it.
The templates on one of our own sites decode HTML entities using eleven chained .split().join() pairs inside a single expression. Page generation on a cache miss went from 15-29 seconds to under 0.3.
Check it worked
curl -sI -H "Accept-Encoding: br" https://yoursite.com/ | grep -iE "content-encoding|cache-control" You want content-encoding: br on the page, and max-age=31536000, immutable on an asset URL that carries ?v=.