HTML 缓存失效常因混淆模板与HTTP缓存导致;index.html需按页面动态性配置Cache-Control:静态页可用public,max-age=3600,动态页须用private,max-age=0,must-revalidate或no-store;敏感页禁用缓存;meta标签无效;JS应defer/async控制阻塞;资源须带内容哈希并启用Gzip/Brotli压缩。

HTML 模板本身不能被“缓存”来提升加载速度——真正起作用的是浏览器对 HTML 文件的 HTTP 缓存,而模板结构只影响解析效率。混淆这两者,是线上故障最常见的源头之一。
Cache-Control 响应头必须配对页面动态性
给 index.html 加 public, max-age=3600 是多数人踩的第一个坑:它会让用户卡在旧版本 HTML 里,哪怕你已上线新 JS、改了按钮文案、甚至删掉了某个 div。
- 静态站点(如文档页、博客文章)可用
public, max-age=3600,但需确保所有资源路径含内容哈希(如main.a1b2c3.js) - 带用户态的页面(仪表盘、订单页)必须用
private, max-age=0, must-revalidate或直接no-cache—— 允许缓存,但每次都要验证 - 登录页、支付确认页等敏感页,用
no-store,彻底禁用缓存 -
meta http-equiv="Cache-Control"在 Chrome/Firefox/Edge 中完全无效,仅旧版 Safari 可能降级识别,别依赖它
HTML 内联与 defer/async 控制解析阻塞
浏览器解析 HTML 是流式的,<script></script> 标签位置和属性直接决定白屏时长。不是“加了缓存就不用管模板”,而是缓存再快,也救不了被阻塞的 DOM 构建。
-
<script></script>绝对不要放在里且不加defer或async—— 这会暂停整个 HTML 解析 - 业务逻辑脚本(如表单校验、组件初始化)优先用
defer:下载不阻塞,执行在 DOM 构建完成后 - 无依赖埋点脚本(如 GA、Sentry)用
async:下载不阻塞,执行时机不可控,但不影响主流程 - 内联 JS 控制在 1KB 以内;超量必须外链,否则 parser blocking 时间在低端设备上明显拉长
服务端压缩 + 构建产物哈希才是缓存生效前提
光设 Cache-Control 不够,如果 HTML 引用的 main.js 没缓存,或者文件名没变但内容变了,用户照样加载旧逻辑。
立即学习“前端免费学习笔记(深入)”;
- 启用 Gzip 或 Brotli 压缩:Nginx 配置
gzip on;或brotli on;,HTML 体积通常缩小 50%~70% - JS/CSS 必须启用 content hash 输出(Webpack 的
contenthash,Vite 的默认行为),再配Cache-Control: public, max-age=31536000 - 构建工具如
html-webpack-plugin开启cache: true可加速本地开发编译,但它不改变浏览器缓存行为 - CDN 或反向代理(如 Nginx location 块)要单独配置 HTML 缓存策略,不能和静态资源混用同一规则
最常被忽略的点:HTML 缓存时间越长,对 JS/CSS 路径稳定性的要求越高。一个没带哈希的 main.js,配上 max-age=31536000,等于把用户永远钉在旧版本上。



















