如何在Workbox Service Worker中添加资源链接实现缓存优先后网络请求
Workbox 缓存优先策略配置方案
你目前的代码混合了原生Service Worker的缓存逻辑和Workbox逻辑,可直接用Workbox的预置能力完成需求,避免逻辑冲突。
步骤1:预缓存指定静态资源
如果需要在Service Worker安装阶段就提前缓存指定的资源链接,直接修改现有addAll数组即可,把需要预缓存的资源路径添加到数组中:
this.addEventListener('install', event => { event.waitUntil( caches.open(currentCache.offline).then(function(cache) { return cache.addAll([ offlineUrl, // 示例:添加需要预缓存的资源链接 '/static/css/main.css', '/static/js/app.js', '/static/logo.png' ]); }) ); // 可选配置:跳过等待直接激活新Service Worker self.skipWaiting(); });
步骤2:配置缓存优先规则
你当前已经引入的CacheFirst策略,就是你需要的优先从缓存加载、缓存不存在时再请求网络的逻辑。如果需要覆盖更多资源类型,可以调整匹配规则:
workbox.routing.registerRoute( // 匹配指定类型的静态资源 ({request}) => ['image', 'style', 'script', 'font'].includes(request.destination), new workbox.strategies.CacheFirst({ // 可选配置:指定缓存名称方便管理 cacheName: 'static-resources' + cacheVersion, // 可选配置:添加缓存过期规则,避免缓存无限堆积 plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 200, // 最多缓存200个资源 maxAgeSeconds: 30 * 24 * 60 * 60, // 缓存有效期30天 }), ], }) );
步骤3:清理冲突逻辑
自定义的原生fetch事件会和Workbox的路由规则冲突,建议删除自定义fetch事件,用Workbox的插件实现页面离线回退逻辑:
// 页面请求:先走网络,网络请求失败时返回离线页 workbox.routing.registerRoute( ({request}) => request.mode === 'navigate' || (request.method === 'GET' && request.headers.get('accept').includes('text/html')), new workbox.strategies.NetworkOnly({ plugins: [ new workbox.routing.CatchOnlyPlugin([ new workbox.strategies.CacheOnly({ cacheName: currentCache.offline, matchOptions: { ignoreSearch: true } }) ]) ] }) );
完整示例代码
importScripts('/local-res/comps/wb-ox-sw.js'); 'use strict'; const cacheVersion = 1; const currentCache = { offline: 'OFFSERVE' + cacheVersion, static: 'STATICRES' + cacheVersion }; const offlineUrl = '/mes_srv_off.html'; // 预缓存资源列表,直接在这里添加你需要预缓存的资源链接 const precacheAssets = [ offlineUrl, '/static/css/main.css', '/static/js/app.js', '/static/logo.png' ]; // 安装阶段预缓存资源 this.addEventListener('install', event => { event.waitUntil( caches.open(currentCache.offline).then(cache => { return cache.addAll(precacheAssets); }).then(() => self.skipWaiting()) ); }); // 激活阶段清理旧版本缓存 this.addEventListener('activate', event => { event.waitUntil( caches.keys().then(cacheNames => { return cacheNames.filter(cacheName => { return cacheName !== currentCache.offline && cacheName !== currentCache.static; }).map(cacheName => caches.delete(cacheName)); }).then(() => self.clients.claim()) ); }); // 静态资源走缓存优先策略 workbox.routing.registerRoute( ({request}) => ['image', 'style', 'script', 'font'].includes(request.destination), new workbox.strategies.CacheFirst({ cacheName: currentCache.static, plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 200, maxAgeSeconds: 30 * 24 * 60 * 60 }) ] }) ); // 页面走网络优先,失败回退离线页 workbox.routing.registerRoute( ({request}) => request.mode === 'navigate' || (request.method === 'GET' && request.headers.get('accept').includes('text/html')), new workbox.strategies.NetworkFirst({ networkTimeoutSeconds: 3, plugins: [ new workbox.routing.CatchOnlyPlugin([ new workbox.strategies.CacheOnly({ cacheName: currentCache.offline, matchOptions: { ignoreSearch: true } }) ]) ] }) );
内容的提问来源于stack exchange,提问作者Moon Monoar
相关产品推荐
相关产品推荐

