HTML离线能力依赖缓存但不等同于HTTP缓存;manifest需显式声明资源,Service Worker通过install事件主动缓存,且须区分HTML(network-first)与静态资源(cache-first)的策略。

HTML 离线(即 manifest 文件或现代的 Service Worker)和浏览器缓存机制**有关系,但不是一回事**——离线能力依赖缓存,但普通 HTTP 缓存无法实现真正的“离线可用”。
HTML 离线靠的是资源预声明,不是靠 Cache-Control
传统 HTTP 缓存(比如设置 Cache-Control: max-age=3600)只影响资源是否从本地磁盘读取,不控制“页面能否在断网时打开”。用户关掉网络后直接访问 index.html,如果该 HTML 本身没被缓存或依赖的 JS/CSS/图片加载失败,页面照样白屏或报错。
-
manifest(已废弃)要求你在cache.manifest里**显式列出所有要离线使用的文件**,浏览器才会在首次访问时下载并持久保存 -
Service Worker则通过install事件里的caches.open().addAll()主动拉取并缓存资源,粒度更细、可控性更强 - 仅靠
Expires或ETag响应头,无法让 HTML 页面“自带离线能力”——它只是告诉浏览器“这个文件可以缓存多久”,不触发离线安装逻辑
Service Worker 的缓存策略必须区分“页面 HTML”和“静态资源”
很多开发者把 index.html 和 app.js 用同一个缓存策略处理,结果导致 HTML 更新后用户仍看到旧版本——因为 HTML 被缓存在 Service Worker 里,而浏览器又没重新请求它。
- 推荐对 HTML 使用
network-first:每次访问先尝试联网获取最新版,失败再 fallback 到缓存(需在fetch事件中手动判断event.request.destination === 'document') - 对 JS/CSS/图片等静态资源,用
cache-first并配合版本号或内容哈希(如app.a1b2c3.js),避免缓存污染 - 别忘了在
activate阶段调用caches.delete()清理旧缓存,否则不同版本资源可能共存导致混乱
离线页面的 index.html 必须能自包含运行
常见错误是:开发时一切正常,一断网就空白。往往是因为 HTML 里写了相对路径的 <script src="js/main.js"></script>,但 Service Worker 没缓存 js/main.js,或者缓存了却没匹配到请求路径(比如请求的是 /js/main.js,但缓存键是 js/main.js)。
立即学习“前端免费学习笔记(深入)”;
- 检查
fetch事件中是否对event.request.destination做了正确分类:'script'、'style'、'image'、'document' - 确保
caches.match(event.request)能命中——注意 URL 完全一致(含查询参数、协议、端口) - 调试时打开 Chrome DevTools → Application → Cache Storage,手动查看缓存内容是否齐全、路径是否匹配
真正难的不是写几行 Service Worker 代码,而是想清楚每个资源的生命周期:它该什么时候下载?什么时候更新?断网时要不要 fallback?哪些该强制刷新,哪些该永远复用?这些决策一旦定错,缓存反而会掩盖问题,让 bug 更难定位。



















