如何修改Create React App生成的PWA的缓存策略为网络优先
修改只需要调整service-worker.js文件即可,具体操作如下:
步骤1:导入网络优先策略
在service-worker.js的导入部分,新增NetworkFirst的引入:
// 原导入行 import { StaleWhileRevalidate } from 'workbox-strategies'; // 修改为 import { StaleWhileRevalidate, NetworkFirst } from 'workbox-strategies';
步骤2:修改静态资源缓存规则
现有代码里的png图片缓存默认用的是 stale-while-revalidate 策略,直接替换为NetworkFirst即可,可按需添加网络超时配置,避免弱网环境下等待时间过长:
registerRoute( ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // 替换原有StaleWhileRevalidate为NetworkFirst new NetworkFirst({ cacheName: 'images', // 可选:网络请求超过3秒就直接返回缓存内容 networkTimeoutSeconds: 3, plugins: [ new ExpirationPlugin({ maxEntries: 50 }), ], }) );
步骤3:(可选)页面导航请求改为网络优先
默认配置下导航请求会直接返回缓存的index.html实现App Shell效果,如果你需要页面打开时优先拉取最新的页面内容,可修改导航路由的处理逻辑:
registerRoute( ({ request, url }) => { if (request.mode !== 'navigate') return false; if (url.pathname.startsWith('/_')) return false; if (url.pathname.match(fileExtensionRegexp)) return false; return true; }, // 替换原有createHandlerBoundToURL配置 new NetworkFirst({ cacheName: 'html-cache', networkTimeoutSeconds: 2, }) );
完整修改后的service-worker.js参考
/* eslint-disable no-restricted-globals */ import { clientsClaim } from 'workbox-core'; import { ExpirationPlugin } from 'workbox-expiration'; import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching'; import { registerRoute } from 'workbox-routing'; import { StaleWhileRevalidate, NetworkFirst } from 'workbox-strategies'; clientsClaim(); precacheAndRoute(self.__WB_MANIFEST); const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$'); // 导航请求网络优先配置(不需要的话可以保留原来的createHandlerBoundToURL逻辑) 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: 'html-cache', networkTimeoutSeconds: 2, }) ); // 图片资源网络优先配置 registerRoute( ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), new NetworkFirst({ cacheName: 'images', networkTimeoutSeconds: 3, plugins: [ new ExpirationPlugin({ maxEntries: 50 }), ], }) ); self.addEventListener('message', (event) => { if (event.data && event.data.type === 'SKIP_WAITING') { self.skipWaiting(); } }); // 其他自定义逻辑可写在下方
注意事项
- 配置完成后重新构建部署项目,新的service worker会在用户下次打开应用时自动生效
- 网络优先策略下,有网络时会优先拉取最新资源,仅在断网或者网络超过设定的超时时间时才会返回缓存内容
- 如果有其他类型的资源(比如其他格式的静态资源、API请求等)需要设置网络优先,参照上述规则新增对应的
registerRoute配置即可
内容的提问来源于stack exchange,提问作者Rawand
相关产品推荐
相关产品推荐

