Загрузка…
Загрузка…
Сжатие текста — cheapest big win: precompress static на build, dynamic gzip/brotli на лету только для text MIME types.
# Server: negotiate automatically. Serve PRECOMPRESSED static .br/.gz if present,
# otherwise compress dynamic responses on the fly — but only text types.
gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_comp_level 6; # dynamic: balance CPU vs ratio (NOT 9)
gzip_min_length 1024; # don't bother below ~1KB — overhead > savings
brotli on;
brotli_static on; # serve app.js.br built at deploy time (level 11)
brotli_comp_level 5; # dynamic Brotli: low level, still beats gzip
brotli_types text/css application/javascript application/json image/svg+xml;// Build step: precompress static assets at MAX level, once.
import { brotliCompressSync, gzipSync, constants } from 'node:zlib';
const js = readFileSync('dist/app.js');
writeFileSync('dist/app.js.br',
brotliCompressSync(js, { params: { [constants.BROTLI_PARAM_QUALITY]: 11 } }));
writeFileSync('dist/app.js.gz',
gzipSync(js, { level: 9 })); // fallback for the rare client without brStatic .br level 11 один раз на deploy; dynamic level 6 gzip / 5 brotli — balance CPU. min_length ~1KB. SVG — text, JPEG/WOFF2 — уже compressed, не трогать.
Brotli-11 static + gzip/br dynamic для text; scope MIME types; не compress already-compressed binaries.
