nginx需同时实现html协商缓存与静态资源强缓存:index.html设cache-control: no-cache启用etag验证返回304;哈希文件如app.abc123.js配expires 1y和immutable;启用gzip_static/brotli_static预压缩及open_file_cache优化元数据读取。

核心思路是让 Nginx 同时承担静态资源缓存代理和首屏 HTML 协商缓存双重角色,避免每次刷新都重新拉取 index.html 和它所依赖的带哈希的 JS/CSS。
精准控制 index.html 的协商缓存
单页应用的入口文件 index.html 本身体积小,但内容敏感——它决定了后续加载哪些 chunk。不能长期缓存,也不能每次都全量重载。
- 设置
Cache-Control: no-cache,强制浏览器发起条件请求 - 启用
Last-Modified或更可靠的ETag(Nginx 默认开启) - 这样首次访问返回 200 + ETag,后续刷新发送
If-None-Match,服务端比对后直接返回 304,不传输 body
为带哈希的静态资源设置强缓存
Webpack/Vite 打包生成的 app.abc123.js、style.def456.css 等文件名含内容哈希,内容不变则 URL 不变,适合长期缓存。
- 匹配哈希类文件名:
location ~* \.[a-f0-9]{6,}\.(js|css|json|svg)$ - 配置
expires 1y;,自动写入Cache-Control: public, max-age=31536000 - 追加
add_header Cache-Control "public, immutable";,防止浏览器在过期前再次验证
启用 Gzip 与 Brotli(可选)压缩
文本类资源(JS/CSS/HTML)经压缩后体积常减少 60%~70%,显著缩短传输耗时。
- 确保构建产物已生成
.gz文件(如app.js.gz),并开启gzip_static on; - 比实时压缩更轻量,不消耗 CPU,优先返回预压缩文件
- 若支持 Brotli(现代浏览器),可用
brotli_static on;替代或补充
配置 open_file_cache 提升文件元数据读取效率
Nginx 频繁读取静态文件时,反复 stat() 操作会成为瓶颈,尤其在高并发下。
- 添加全局配置:
open_file_cache max=10000 inactive=60s; -
open_file_cache_valid 30s;定期校验缓存有效性 -
open_file_cache_min_uses 2;至少被访问两次才纳入缓存,过滤临时请求 - 配合
sendfile on;和tcp_nopush on;,提升内核级文件传输效率











