改完网页,部署成功,构建也没报错。打开网站一看:怎么还是旧的?刷新一次,还是旧的。换个浏览器,居然又变成新的。
这种场景特别容易让人怀疑代码、Cloudflare、DNS,甚至开始怀疑自己刚才到底有没有保存文件。其实很多时候代码没有问题,真正赖着不走的是缓存。
缓存到底在干什么
网页通常包含 HTML、CSS、JavaScript、图片、字体等资源。如果每次打开页面都从服务器重新下载全部文件,不仅浪费流量,速度也会明显变慢。所以浏览器会保存一部分已经下载过的资源,下次访问时优先复用。
这本来是好事。问题在于网站刚更新时,浏览器手里的旧资源可能还没有过期,于是服务器已经活在今天,浏览器却还活在昨天。
普通刷新为什么不一定管用
很多人以为点一下刷新就是“重新下载整页”。实际并不总是这样。浏览器仍可能继续使用缓存中的 CSS、JS、图片或字体。于是会出现一种很别扭的混搭:HTML 是新的,JavaScript 却还是旧的。
桌面 Chrome 或 Edge 中,Ctrl + Shift + R、Ctrl + F5一类强制刷新通常会更积极地重新验证资源。手机端不同浏览器差异更大,可以用无痕模式、另一个浏览器或清理当前站点数据做对照。
Cloudflare 也可能有缓存
如果站点经过 CDN,路径会变成:源站 → Cloudflare 边缘节点 → 浏览器。旧内容可能留在浏览器,也可能留在 CDN。清了本地缓存仍然看到旧内容时,就要继续确认 CDN 缓存策略,而不是只盯着前端代码。
为什么文件名后面常有一串奇怪字符
现代前端构建经常把 app.js 变成 app.8fa2c1.js。这串 Hash 很有用:文件内容改变,文件名也改变。浏览器看到一个从未见过的新 URL,就会重新下载,而不是继续抱着旧缓存不撒手。
PWA 还有一个隐藏关卡:Service Worker
PWA 为了离线访问和快速启动,经常由 Service Worker 管理 Cache Storage。如果更新策略写得不好,就可能发生“部署三版,用户还在上一版”的经典事故。
这时普通刷新甚至可能不够。要检查 Service Worker 是否拿到新版本、旧缓存是否清理、HTML 是否被过度缓存,以及新 Worker 是否已经激活。手机网页出现这种问题时,可以配合 Lab 的手机网页调试指南查看 Application、Cache Storage 和 Service Worker 状态。
一个不容易把现场越修越乱的顺序
- 先记录当前页面表现,不要马上改代码。
- 使用无痕模式或另一浏览器对照。
- 强制刷新或仅清理该站点的数据。
- 如果多台设备都旧,再检查 CDN 缓存。
- PWA 单独检查 Service Worker 与 Cache Storage。
- 最后才重新判断部署是否真的失败。
缓存不是坏东西。没有缓存,现代网站会慢不少。真正难的不是“要不要缓存”,而是什么时候该让旧东西失效。