HTML文件必须设为no-cache或max-age=0,must-revalidate,因其作为动态入口不可长期缓存;静态资源需文件名哈希+immutable长期缓存;meta标签对缓存无效。

HTML 文件本身不能被长期缓存,哪怕你用了 index.a1b2c3.html 这种带哈希的文件名——只要它是动态路由入口或 SSR 渲染起点,就必须设为 no-cache 或 max-age=0。否则用户刷新页面看到的永远是旧 HTML,JS 路径 404、按钮点击无反应、文案没更新,都是缓存惹的祸。
为什么 meta http-equiv="Cache-Control" 基本无效
这个写法在 Chrome、Firefox、Edge 中完全不生效,只在某些老旧 WebView 里可能被当作降级 fallback。浏览器只认 HTTP 响应头里的 Cache-Control 字段。如果你在 index.html 里写了:<meta http-equiv="Cache-Control" content="max-age=3600">,DevTools 的 Network 面板里根本看不到它出现在响应头中,也就起不到任何作用。
验证是否生效的唯一方式:打开 DevTools → Network → 点击 HTML 请求 → 查看 Response Headers 是否有 Cache-Control 字段。
HTML 缓存必须用 no-cache 或 max-age=0
对所有作为入口的 HTML(如 /、/article/123、/dashboard),服务端响应头必须明确禁止强缓存:
立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- Nginx 配置示例:
location = /index.html { add_header Cache-Control "no-cache, must-revalidate"; } - Express 示例:
res.set("Cache-Control", "no-cache, must-revalidate"); - 纯静态托管(如 Vercel)需在
vercel.json中声明:"headers": [{ "source": "/(.*)", "headers": [{ "key": "Cache-Control", "value": "no-cache, must-revalidate" }] }]
注意:no-cache 不等于“不缓存”,它表示每次请求都得向服务端验证(发 If-None-Match),若返回 304 Not Modified 才复用本地副本——这能省传输体积,但无法跳过网络往返,首屏延迟依然存在。
静态资源必须靠文件名哈希 + 长期缓存
真正影响首屏速度的是 HTML 引用的 JS/CSS/图片,它们和 HTML 的缓存策略必须解耦:
- 构建时启用
contenthash(Webpack/Vite/Rollup 默认支持),生成类似main.ea7f2d.js的文件名 - 服务端对这类资源响应头设为:
Cache-Control: public, max-age=31536000, immutable - 图片若由 CMS 上传、无法加哈希,则依赖
ETag或Last-Modified协商缓存;Nginx 默认开启etag on,但需确认 CDN 没覆盖它
immutable 指令很关键:它告诉浏览器“这个 URL 对应的内容永远不会变”,后续即使用户强制刷新(Ctrl+R),也不会重新发起请求——这是长期缓存安全落地的前提。
HTML 模板结构比缓存更早决定首屏是否卡顿
浏览器是流式解析 HTML 的,任何阻塞行为都会中断后续标签处理。缓存再好,也救不了结构不当的模板:
-
<script>标签放在<head>里且没加defer或async,会立即下载执行,暂停整个 DOM 构建 - 内联 JS 超过 1KB(如埋点配置、初始化对象)就该外链,否则 parser blocking 时间明显拉长
-
<meta charset>必须出现在第一行,否则编码识别延迟可能触发整页重解析 - 避免在开头堆砌多个第三方
<script>,它们串行阻塞,弱网下 TTFB 放大效应极明显
最常被忽略的一点:服务端压缩(Brotli/Gzip)比前端“精简 HTML”有效得多。HTML 体积小,但压缩后通常能缩小 50%~70%,且无需改动模板结构;而手动删空格、合并换行极易破坏语义,比如误删 <table> 的必需属性导致渲染异常。


















