文档首页> 技术教程> 带 hash 的静态资源缓存策略

带 hash 的静态资源缓存策略

发布时间:2026-08-03 20:50        更新时间:2026-08-04 06:53
文件名里带内容 hash 的静态资源(如 app.3f2a1b.js),是唯一适合放心设一年长缓存的资源类型,其他资源都要保守对待。前提是构建工具的保证:内容变了 hash 就变,文件名跟着变,市面上的打包器默认都这么实现,不需要额外配置。 hash 为什么可靠 hash 是按文件内容算出的指纹,构建工具里通常叫 contenthash。发新版本时旧文件名不会被复用:改一行代码,app.3f2a1b.js 就变成 app.9c4d2e.js,浏览器缓存的旧文件名自然失效;内容不变,文件名不变,同一份文件反复构建指纹也一致,缓存永不失准。所以对这类资源,策略可以下狠手: location ~* /assets/.*\.(js|css|png|jpg|svg|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } immutable 告诉浏览器连 304 协商请求都不用发,直接用本地缓存,二次访问零请求,页面二次加载的速度提升非常直观。站点前面还有 CDN 或反向代理的,确认中间层遵循并透传这套响应头,任何一层擅自改写或吞掉,策略就会打折,先查中间层再查源站,顺序别搞反。 index.html 是关键例外 HTML 不能这么干:它是资源入口,里面写着当前版本的 hash 文件名。HTML 一旦被缓存,用户会拿旧 HTML 去引用可能已删除的旧资源,白屏和样式错乱就来了,而且只有部分用户中招,极难复现。HTML 必须单独设: location = /index.html { add_header Cache-Control "no-cache"; } no-cache 不是不缓存,是每次回源校验:服务器按 ETag(资源指纹)或 Last-Modified 判断内容有没有变,没变就回一个不含正文的 304,开销很小。发布顺序因此有个约定:先传新版带 hash 的资源,最后替换 index.html,任何时刻线上都有完整的一套;回滚旧版本时 index.html 要跟着一起回,它引用的是旧文件名。 验证响应头 curl -I https://example.com/assets/app.3f2a1b.js,应看到 max-age=31536000 和 immutable;curl -I https://example.com/,应看到 no-cache。浏览器端再验证一遍:强刷后二次刷新,带 hash 资源在 Network 面板里应显示 from disk cache 或 from memory cache,HTML 则每次都有网络请求(哪怕只是个 304)。两类头各归各位,这套策略才算配完;以后打包工具升级,回来再跑一遍这个验证。