使用Workbox开发PWA时,预缓存能否采用Network-First策略?
问题描述
使用Create React App生成的Workbox服务工作者代码如下:
// in service-worker.js precacheAndRoute(self.__WB_MANIFEST); // Set up App Shell-style routing, so that all navigation requests // are fulfilled with your index.html shell. const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$'); registerRoute( // Return false to exempt requests from being fulfilled by index.html. ({ request, url }) => { console.log(request, url) // If this isn't a navigation, skip. if (request.mode !== 'navigate') { return false; } // If this is a URL that starts with /_, skip. if (url.pathname.startsWith('/_')) { return false; } // If this looks like a URL for a resource with file extension, skip. if (url.pathname.match(fileExtensionRegexp)) { return false; } // Return true to signal that we want to use the handler. return true; }, createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html') );
代码可正常实现离线刷新,但修改页面内容后无法更新。请问在使用Google Workbox时,能否为预缓存采用“Network-First”策略?
解决方案
Workbox的预缓存(precacheAndRoute)机制本身是基于Cache-First策略设计的,而且预缓存的资源(如JS、CSS、图片等)在构建时都会带上唯一哈希值,当资源内容变更时,哈希值会同步更新,Workbox会自动替换旧的缓存资源,所以不需要给预缓存资源改用Network-First策略。
你遇到的更新问题,核心在于不带哈希值的index.html导航请求——当前代码会直接返回缓存中的index.html,导致内容更新后无法及时获取最新版本。针对这种情况,你可以单独给导航请求配置Network-First策略,而预缓存的其他资源保持原有逻辑不变:
修改后的代码
// in service-worker.js import { NetworkFirst, CacheableResponsePlugin } from 'workbox-strategies'; import { precacheAndRoute, registerRoute } from 'workbox-routing'; precacheAndRoute(self.__WB_MANIFEST); const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$'); registerRoute( ({ request, url }) => { // 保留原有的导航请求匹配逻辑 if (request.mode !== 'navigate') return false; if (url.pathname.startsWith('/_')) return false; if (url.pathname.match(fileExtensionRegexp)) return false; return true; }, new NetworkFirst({ cacheName: 'navigations', // 单独给导航请求创建缓存空间 plugins: [ // 只缓存成功的HTTP响应(状态码200) new CacheableResponsePlugin({ statuses: [200], }), ], }) );
逻辑说明
- 导航请求会优先尝试从网络获取最新的
index.html,如果网络正常,就用最新内容并更新缓存; - 当网络离线时,会回退到缓存中的
index.html,保证离线可用性; - 预缓存的静态资源(带哈希)依然沿用Cache-First策略,内容变更时通过哈希更新自动替换缓存,不会出现更新延迟问题。
内容的提问来源于stack exchange,提问作者dansch
相关产品推荐
相关产品推荐

