HTML模板本身不缓存,真正出问题的是构建产物中静态资源的引用方式和缓存策略没对齐——尤其当模板被服务端渲染(SSR)或静态生成(SSG)时,index.html 里写的 script 和 link 路径如果没带哈希或版本号,浏览器就会一直用旧 JS/CSS。

HTML模板本身不缓存,真正出问题的是构建产物中静态资源的引用方式和缓存策略没对齐——尤其当模板被服务端渲染(SSR)或静态生成(SSG)时,index.html 里写的 script 和 link 路径如果没带哈希或版本号,浏览器就会一直用旧 JS/CSS。
HTML模板里写死的资源路径没更新
这是最常踩的坑:Webpack/Vite 打包后生成了 app.a1b2c3.js,但你的 HTML 模板里还是 <script src="app.js"></script>。浏览器缓存了旧 app.js,新逻辑根本加载不上。
- 手写模板必须配合构建插件自动注入哈希路径,比如 Webpack 的
html-webpack-plugin、Vite 的vite-plugin-html - 纯静态 HTML(如托管在 Nginx)不能靠手动改
v=1.2.3参数——参数变了但文件没变,CDN 仍返回旧内容 - 服务端模板(PHP/Node.js)要确保每次部署都重新渲染 HTML,而不是缓存了带旧路径的 HTML 片段
构建工具没正确处理 CSS/JS 的缓存头
即使文件名加了哈希,如果服务器返回的响应头是 Cache-Control: max-age=31536000,浏览器就会长期强缓存这些资源。下次你发新版,用户访问时仍会加载旧哈希文件(因为旧哈希路径还在 HTML 里)。
- 确认构建产物中所有带哈希的静态资源,都被服务器配置为长期缓存(
max-age=31536000),这是前提 - 但
index.html必须设为不强缓存:Cache-Control: no-cache, must-revalidate,否则 HTML 本身卡在旧版本,新哈希路径根本不会被请求 - CDN(如 Cloudflare)默认可能把
/index.html当静态资源缓存一天,需单独配置路径规则,排除/index.html
Service Worker 拦截并缓存了旧 HTML 或资源
一旦注册了 Service Worker,它就接管所有请求。如果 SW 脚本里用了 cache.match() 且没做版本清理,哪怕你更新了 HTML 和 JS,SW 仍会返回上次缓存的内容——连 Ctrl+F5 都无效。
立即学习“前端免费学习笔记(深入)”;
- 每次更新 SW 脚本内容(哪怕只加个空格),浏览器才会触发
install事件,进而激活新版本 - 不要在 SW 里无条件返回缓存;至少对
index.html做网络优先:await fetch(event.request).catch(() => caches.match(event.request)) - 避免用
skipWaiting()强制激活新 SW,除非你确认旧缓存已清空,否则容易导致 HTML 和 JS 版本错配
真正的兼容性不在标签写法,而在构建产物与缓存策略的咬合精度——一个哈希没注入、一个响应头设错、一个 SW 没升级,都会让整个更新链路失效。这些环节必须全部对齐,缺一不可。



















