Compression
Davaux has built-in response compression for both dynamic routes and files served from public/. Enable it via performance.compress in davaux.config.ts. No package to install.
Basic usage
// davaux.config.ts
import { defineConfig } from 'davaux/config'
export default defineConfig({
performance: {
compress: true,
},
})
Brotli is used when the client supports it, gzip otherwise, deflate as a last resort — negotiated automatically from the Accept-Encoding request header.
With options
export default defineConfig({
performance: {
compress: {
encodings: ['br', 'gzip', 'deflate'], // preference order — default
filter: (contentType) => contentType.startsWith('text/'),
},
},
})
| Option | Type | Default | Description |
|---|---|---|---|
encodings | Array<'br' | 'gzip' | 'deflate'> | ['br', 'gzip', 'deflate'] | Supported encodings in preference order |
filter | (contentType: string) => boolean | Compresses text and common app types | Custom function to decide per content-type |
Limit to gzip only
Useful when deploying behind infrastructure that doesn't support brotli:
performance: { compress: { encodings: ['gzip'] } }
What gets compressed
By default the following content types are compressed:
| Content-Type | Compressed |
|---|---|
text/html | ✓ |
text/css | ✓ |
text/plain | ✓ |
application/javascript | ✓ |
application/json | ✓ |
application/xml | ✓ |
image/svg+xml | ✓ |
| Images (jpg, png, webp…) | — already compressed |
| Fonts (woff2…) | — already compressed |
How it works
Compression applies at two levels:
Dynamic routes — At the start of each request, Davaux wraps res.writeHead, res.write, and res.end. When the route or middleware calls writeHead, the Content-Type is inspected to decide whether to compress. If yes, subsequent writes are piped through a Node.js zlib transform stream (brotli at quality 4, gzip/deflate at level 6). Content-Length is removed and Content-Encoding + Vary: Accept-Encoding are set. Streaming responses (ctx.defer()) are compressed chunk-by-chunk automatically.
Static files — Files served from public/ and /_davaux/ (islands, client bundle, styles) are piped through the same zlib streams before being written to the socket.
When to skip it
If you deploy behind a reverse proxy (nginx, Caddy, AWS CloudFront) that handles compression, leave compress unset. The proxy approach offloads CPU from Node.js and typically caches compressed responses — enabling both would waste CPU without benefit. Most proxies detect an existing Content-Encoding header and skip re-compression, but there is no upside to doing the work twice.