Webpack配置Workbox实现PWA预缓存index.html达成离线访问的问题咨询
问题根因分析
- index.html未被缓存核心有两个原因:
- Workbox的
GenerateSW默认仅将webpack构建流程产出的静态资源加入预缓存清单,如果你的index.html是放在静态目录未经过webpack构建链路处理,不会被自动纳入预缓存 - 你当前配置的
runtimeCaching规则仅匹配后缀带.html的请求,且runtimeCaching仅处理Service Worker注册完成之后发起的请求,用户首次访问时index.html请求发生在SW激活前,不会被runtime规则命中缓存
- Workbox的
修正后的配置方案
直接修改WorkboxPlugin.GenerateSW部分的配置即可,修改后的完整配置如下:
new WorkboxPlugin.GenerateSW({ exclude: ['./static/1pixel.png'], maximumFileSizeToCacheInBytes: 6291456, clientsClaim: true, skipWaiting: true, // 手动将index.html加入预缓存清单,SW激活时直接缓存,无需等待请求 // 若你的index.html由html-webpack-plugin生成,可省略该配置,Workbox会自动识别纳入预缓存 additionalManifestEntries: [ // 如果项目部署在子目录,需要调整url为对应路径,比如'/subpath/index.html' { url: '/index.html', revision: Date.now().toString() } ], // 可选:开启导航预加载,提升离线页面打开速度 navigationPreload: true, runtimeCaching: [ // 匹配所有页面导航请求,适配SPA无后缀路由场景,使用你最初期望的StaleWhileRevalidate策略 { handler: 'StaleWhileRevalidate', urlPattern: ({ request }) => request.mode === 'navigate', options: { cacheName: 'html-cache', cacheableResponse: { statuses: [200] } } }, { handler: 'CacheFirst', urlPattern: /\.(?:js|css|woff2?|ttf|eot|ico|svg|png|jpe?g|gif)$/, options: { cacheName: 'static-assets-cache', cacheableResponse: { statuses: [200] } } } ] })
配置说明
additionalManifestEntries:手动指定需要加入预缓存的资源,不管是否经过webpack构建都会被纳入预缓存清单,SW安装阶段就会主动请求缓存这些资源,保证首次加载后就存在缓存- 导航请求匹配规则:通过
request.mode === 'navigate'匹配所有页面访问请求,不管路由是否带.html后缀,适配SPA路由场景,StaleWhileRevalidate策略会优先返回缓存内容保证加载速度,同时后台拉取最新版本更新缓存 - 调整后的静态资源匹配规则覆盖了字体、图片等所有静态资源类型,不需要额外单独配置
验证步骤
- 重新构建项目后,查看生成的预缓存清单文件(一般名为
precache-manifest.xxx.js),确认/index.html已经在清单列表中 - 首次联网加载应用后,打开浏览器DevTools -> Application -> Cache Storage,确认
html-cache和static-assets-cache中都有对应资源 - 开启浏览器离线模式,刷新页面即可正常访问
内容的提问来源于stack exchange,提问作者IncrediblePony
相关产品推荐
相关产品推荐

