做 Web 性能优化,缓存是性价比最高的一步——不用换服务器、不用改业务代码,把响应头配对,重复请求就能少一大半。但缓存也是最容易配错的一环:“更新了用户看不到新版本”“改了配置还是没生效”,多半是强缓存与协商缓存没分清。这篇把它们彻底讲透。
一、两种缓存:强缓存与协商缓存
| 类型 | 判定依据 | 命中表现 | 谁决定 |
|---|---|---|---|
| 强缓存 | Cache-Control(或 Expires) | 200(from memory/disk cache),不发网络请求 | 浏览器本地直接用 |
| 协商缓存 | ETag / Last-Modified | 304 Not Modified,仍需发请求确认 | 服务器返回 304 或 200 |
记忆锚点:强缓存 = 不发请求直接用;协商缓存 = 发一个“校验请求”问服务器“我没变吧”,服务器说“没变”(304)就继续用本地副本。
二、强缓存的头:Cache-Control 是主角
# 常见取值
Cache-Control: public, max-age=31536000 # 一年,适合带指纹的静态资源
Cache-Control: private, max-age=0 # 仅本用户、不缓存,适合登录后页面
Cache-Control: no-cache # 每次都要到服务器“协商”,不是不缓存
Cache-Control: no-store # 真正不缓存(敏感数据)
Cache-Control: public, max-age=60, stale-while-revalidate=600
- max-age 单位是秒,表示从收到响应起多久内可用;
- 老字段 Expires(HTTP/1.0)是绝对时间,受本地时钟影响,现在以 Cache-Control 为准,两者都有时 Cache-Control 优先;
- no-cache 不是“不用缓存”,而是“每次先用再用,但要先校验”——这正适合 HTML 页面。
三、协商缓存的头:ETag 与 Last-Modified
- Last-Modified / If-Modified-Since:基于文件的最后修改时间,精度到秒,时间没变服务器返回 304;
- ETag / If-None-Match:基于内容的校验值(指纹),内容变指纹才变,比时间更准,是 HTTP/1.1 的推荐方式;
- 两者都带时,服务器以 ETag 校验优先(If-None-Match 优先于 If-Modified-Since)。
# 服务器返回
HTTP/1.1 200 OK
Cache-Control: no-cache
ETag: "64c1a2-5d4e"
# 浏览器再请求时带上
If-None-Match: "64c1a2-5d4e"
# 内容没变 → 服务器返回
HTTP/1.1 304 Not Modified # 不带响应体,省流量省时间
四、工程实践:HTML 与静态资源要区别对待
最经典的策略是“内容指纹 + 长缓存”:
- 构建工具(webpack/Vite)给 JS/CSS 文件名加上内容哈希,如
app.a1b2c3.js——内容变了文件名就变; - 带哈希的静态资源配长缓存(一年):文件永远不变,放心缓存;
- HTML(index.html)配 no-cache:每次都协商校验,一旦返回新页面,就引用了带新哈希的资源,天然实现“更新即生效”;
- 图片、字体等不变资源同样长缓存;需要换图时直接换文件名或加参数。
最常见的线上事故就是这样来的:HTML 被长缓存了,用户永远拿不到新页面;或资源没有指纹还长缓存,发布后老用户白屏、样式错乱。排查时先在浏览器控制台勾选 Disable cache 或强制刷新确认是不是缓存问题。
五、Nginx 里的落地配置
# 带指纹的静态资源:一年强缓存
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# HTML:不缓存,每次协商
location = /index.html {
add_header Cache-Control "no-cache";
}
# 普通页面:短缓存,配合后端协商
location / {
add_header Cache-Control "no-cache";
}
加
immutable 表示“文件绝不会变”,配合指纹资源使用,浏览器可以跳过每次的重新验证,是官方推荐的写法。六、调试缓存:DevTools 里看四个信息
- Size 列:
from memory cache / from disk cache说明强缓存命中; - Status:
304说明走了协商缓存; - Response Headers 里的 Cache-Control、ETag、Last-Modified 值;
- 勾选 Disable cache 后的加载时间对比——能直观看到缓存省了多少。
缓存配对了,静态资源这部分的性能基本就位了。缓存之外,还有压缩、CDN、图片格式等更多优化手段,见前端首屏性能优化清单。