HTML缓存不宜设长max-age,纯静态页可设max-age=300(5分钟),动态页应选no-cache或private,max-age=0,must-revalidate,禁用meta标签,必须由服务端响应头配置。

HTML缓存该设多长的 max-age 才不卡旧版本
HTML 文件不能像 JS/CSS 那样放心设 max-age=31536000,因为它的内容常含动态片段(用户昵称、时间戳、未读数),缓存太久就等于把过期状态“硬塞”给用户。但设成 max-age=0 或 no-cache 又会每次触发验证请求,白白增加 TTFB 和请求数。
实操建议:
- 纯静态 HTML(如文档站首页、博客文章页):用
Cache-Control: public, max-age=300(5 分钟),足够缓解 CDN 回源压力,又不至于让用户卡太久 - 带少量动态内容的页面(如 htmx 加载评论的首页):用
Cache-Control: no-cache,配合可靠的ETag,让服务器决定是否返回304 Not Modified - 含实时数据或敏感信息的页面(后台仪表盘、订单详情):用
Cache-Control: private, max-age=0, must-revalidate,禁止 CDN 缓存,但允许浏览器本地暂存并强制验证 - 绝对不要对所有 HTML 统一配
public, max-age=3600——你改完按钮文案,用户刷新还是旧的,问题不在缓存没生效,而在它太“忠实地”生效了
no-cache 不等于不缓存,但它会让速度变慢
no-cache 是最常被误解的指令:它不阻止浏览器存储响应,只是强制每次使用前向服务器发起条件请求(带 If-None-Match 或 If-Modified-Since)。如果服务器没返回 ETag 或 Last-Modified,或者返回了但值总在变,浏览器就只能重下整个 HTML —— 白跑一次 HTTP 往返,首屏反而更慢。
常见错误现象:
- DevTools Network 面板里 HTML 请求始终是 200(不是 304),即使内容根本没变
- 明明加了
no-cache,用户仍看到旧按钮文案,因为服务器返回了新ETag,但前端 JS 已经基于旧 HTML 执行完毕
实操建议:
- 启用
ETag时,确保它基于 HTML 字节流哈希生成(如 Nginx 的etag on;),而不是时间戳或随机值 - 若后端无法稳定生成内容哈希(比如模板中嵌了微秒级时间),宁可只用
Last-Modified并设为构建时写死的时间戳(如从git log -1 --format=%ct获取) - 避免在 HTML 中插入运行时生成的随机 token 或时间戳——这会让
ETag失效,协商缓存退化为全量重载
immutable 能跳过验证,但只适用于带哈希的 HTML
immutable 指令告诉浏览器:“这个 URL 对应的资源永远不会变”,于是连 F5 刷新都不会发 If-None-Match 请求。但它只对真正“不变”的资源安全——比如 index.a1b2c3.html 这种构建时带内容哈希的文件名。
如果你把 immutable 加在 index.html 上,等于宣告“这个文件永远不更新”,那后续任何发版都无效,用户得清缓存才能看到新结构。
实操建议:
- 只有当 HTML 文件名本身含内容哈希(如 Webpack/Vite 自动生成)时,才配
Cache-Control: public, max-age=31536000, immutable - 静态站点生成器(如 Hugo、Jekyll)输出的
index.html通常不带哈希,此时immutable是危险操作 - CDN 或反向代理(如 Nginx)必须单独为 HTML 配置规则,不能和
.js/.css共用同一段location块,否则容易误套immutable
meta 标签完全不可信,别拿它当缓存开关
在 Chrome/Firefox/Edge 中已被完全忽略,仅极少数旧版 Safari 可能降级识别。它只对直接地址栏访问的 HTML 生效,对 fetch()、iframe、htmx 加载的 HTML 完全无效。
更糟的是:你在 HTML 里写了这行,自己以为缓存开了,结果 DevTools 里根本看不到 Cache-Control 响应头,实际每次都在重新下载——排查时绕一大圈才发现是 meta 标签幻觉。
实操建议:
- 所有缓存策略必须由服务端真实响应头发出:Nginx 用
add_header Cache-Control "public, max-age=300";,Express 用res.set('Cache-Control', 'public, max-age=300'); - 检查是否生效,唯一可靠方式是打开 DevTools → Network → 点开 HTML 请求 → 查看 Response Headers 是否有
Cache-Control字段 - 如果用 Vercel、Netlify 等托管平台,必须通过
_headers或vercel.json显式声明,它们不会自动继承你 HTML 里的 meta
平衡点其实很窄:HTML 缓存既不能太短(失去复访收益),也不能太长(导致版本错乱),更不能靠客户端补丁(meta、JS 清缓存)来掩盖服务端配置缺陷。最容易被忽略的是——缓存策略必须和你的部署流程对齐:文件名是否哈希、模板是否含运行时变量、CDN 是否透传 ETag,缺一环,前面全白搭。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











