PWA离线缓存的真正入口是service worker文件(如sw.js)和manifest.json,而非index.html;index.html仅负责注册service worker,缓存逻辑由sw.js中install事件的cache.addAll()和fetch事件的响应策略决定,manifest.json的start_url仅指定启动页路径,不参与缓存控制。

什么是PWA离线缓存的真正入口
PWA离线缓存没有“HTML代码配置入口”这个说法——index.html本身不是缓存控制点,它只是被缓存的资源之一。真正起作用的是 service worker 文件(通常叫 sw.js)和 manifest.json,而 HTML 只负责注册它们。
常见错误是直接在 index.html 里写一堆缓存逻辑,结果发现离线打不开页面。根本原因:浏览器只按 service worker 的 fetch 事件和 cache.addAll() 等逻辑执行缓存,HTML 不参与决策。
-
index.html必须通过navigator.serviceWorker.register('sw.js')启动 worker -
sw.js必须用self.skipWaiting()和clients.claim()避免旧版本残留 -
manifest.json的start_url和scope决定 PWA 启动时加载哪个 HTML,但它不控制缓存内容
如何让 index.html 成为可离线访问的“入口页”
关键不是“配置HTML”,而是确保 HTML 被 service worker 显式缓存,并且能响应离线 fetch 请求。
- 在
sw.js的install事件中,把index.html加入缓存列表:cache.addAll(['/', '/index.html', '/styles.css']) - 在
fetch事件中,对根路径/或/index.html的请求,必须从 cache 中返回,不能 fallback 到 network(否则离线时失败) - 注意路径匹配:如果
scope是/app/,那index.html实际路径是/app/index.html,缓存和 fetch 匹配都要带前缀 - 开发时用 Chrome DevTools 的 Application → Service Workers → “Update on reload” + “Offline” 模拟验证,别只靠刷新判断
为什么 manifest.json 的 start_url 不等于缓存入口
start_url 只影响用户点击桌面图标或从主屏启动时浏览器加载的初始 URL,它不触发缓存、也不决定哪些文件被存。很多人误以为设了 "start_url": "/offline.html" 就能自动缓存那个文件——其实不会,除非你在 sw.js 里明确 cache.add('/offline.html')。
立即学习“前端免费学习笔记(深入)”;
-
start_url必须与scope同域且可被 service worker 控制(比如scope: "/"时,start_url: "/"才有效) - 如果
start_url指向一个未被缓存的路径(如/dynamic-page),离线启动会白屏或报错net::ERR_FAILED -
display: "standalone"或"minimal-ui"不影响缓存行为,只改 UI 表现
常见离线失败的三个硬坑
-
sw.js 注册失败:检查路径是否 404、MIME 类型是否为 application/javascript(Nginx/Apache 需显式配置)、是否在 HTTPS 下运行(localhost 除外)
- 缓存策略写错:用
cache.match(event.request) 但没处理 undefined 返回值,导致离线时返回空响应而不是 fallback 页面
- HTML 自身引用了未缓存的资源:比如
index.html 里写了 <script src="<a href="https://www.php.cn/link/f95f3b81a76363e2bc6a345198278ab6">https://cdn.example.com/app.js"></a>;,这个外链 JS 不在缓存中,离线时整个页面 JS 失效
sw.js 注册失败:检查路径是否 404、MIME 类型是否为 application/javascript(Nginx/Apache 需显式配置)、是否在 HTTPS 下运行(localhost 除外) cache.match(event.request) 但没处理 undefined 返回值,导致离线时返回空响应而不是 fallback 页面 index.html 里写了 <script src="<a href="https://www.php.cn/link/f95f3b81a76363e2bc6a345198278ab6">https://cdn.example.com/app.js"></a>;,这个外链 JS 不在缓存中,离线时整个页面 JS 失效 service worker 的缓存逻辑是唯一可信入口,HTML 只是载体。漏掉 cache.addAll 里的某个 CSS 或字体文件,就可能让离线页面样式崩塌——这种细节比“怎么写 manifest”更决定成败。



















