最有效的方式是让Nginx直接返回预生成的.gz文件。构建时需为JS、CSS等文本资源生成同名.gz文件且保留源文件;Nginx中在静态资源location块启用gzip_static on,并确保.gz文件与源文件同目录、时间戳同步;gzip_static与gzip on共存但职责分明,前者零CPU开销,后者作兜底。
最有效的方式不是让 Nginx 实时压缩,而是让它直接返回预生成的 .gz 文件——零 CPU 开销、TTFB 最低、压缩率更稳。
所有文本类静态资源(JS、CSS、HTML、SVG、JSON、字体等)在打包时就要生成同名 .gz 文件,原始文件不能删。
compression-webpack-plugin,设 algorithm: 'gzip' 和 deleteOriginalAssets: false
vite-plugin-compression,配置 ext: '.gz',避免误删源文件find /path/to/static -type f ( -name "*.js" -o -name "*.css" -o -name "*.html" ) -exec gzip -c9 {} ; -exec mv {}.gz {}.gz ;
.gz 文件必须与源文件同目录;建议同步修改时间:touch -r app.js app.js.gz,否则可能触发缓存异常或退化为动态压缩gzip_static on 不是全局开关,只在能准确映射磁盘路径的 location 块中生效,且优先级高于 try_files。
location ~* .(js|css|json|svg|woff2?|ttf|eot|html)$ {root /usr/share/nginx/html;
gzip_static on;
}
http 或 server 顶层;不要和 try_files $uri 混用在同一块里——否则 gzip_static 不会触发gzip on 或调高 gzip_comp_level;这些属于兜底策略,与 gzip_static 各司其职仅看 Content-Encoding: gzip 不够,需交叉验证:
curl -I -H "Accept-Encoding: gzip" https://yoursite.com/app.js 获取响应头Content-Length 是否等于本地 app.js.gz 的字节数(ls -l app.js.gz)ETag 是否由 .gz 文件的 inode + mtime 构成(原始文件 ETag 格式不同)Last-Modified 时间戳与 app.js.gz 的修改时间一致.gz 缺失、路径不对,或时间戳未同步——Nginx 会多一次 stat() 系统调用后回退到动态压缩两者推荐共存,但职责分明:
gzip_static 处理已预压缩的静态资源,零 CPU 开销gzip on 作为兜底,处理 API 响应、未打 .gz 的旧资源、或后端透传内容http 块中全局开启:
gzip on;
gzip_min_length 1000;
gzip_types text/html text/css application/javascript application/json text/xml application/xml;
务必包含 text/html
gzip_vary on:开启它会导致 CDN 缓存分裂;实际生产中更推荐关掉,靠 ETag 或 Cache-Control 控制缓存粒度