如何使用workbox-recipes的Warm Strategy Cache?附最小示例
核心结论
warmStrategyCache不会自动创建Service Worker,所有Workbox缓存逻辑必须运行在已激活的Service Worker上下文内,无法直接在页面主线程调用。- 运行时触发缓存预热需要通过主线程和Service Worker的
postMessage通信实现,不支持直接在页面事件触发时调用Workbox方法。 - 跨域托管在Contentful的视频缓存必须配置CORS请求模式,否则会拿到不透明响应,导致缓存失效或播放异常。
最小可行实现代码
1. 页面主线程代码
先完成Service Worker注册,在需要触发预热的业务事件中,向Service Worker传递待预热的视频URL列表即可。
// 入口文件执行逻辑:注册Service Worker if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js').catch(err => console.error('SW注册失败:', err)); }); } /** * 触发Contentful视频缓存预热 * @param {string[]} videoUrls 从Contentful接口获取的视频地址列表 */ async function triggerVideoCacheWarm(videoUrls) { const swRegistration = await navigator.serviceWorker.ready; swRegistration.active.postMessage({ type: 'TRIGGER_VIDEO_WARM', urls: videoUrls }); } // 业务调用示例:在你需要的时机(比如进入视频板块、hover播放按钮、拿到Contentful视频数据后)调用 // const videoList = await fetchContentfulVideoList(); // 你自己的Contentful接口请求逻辑 // triggerVideoCacheWarm(videoList.map(item => item.videoUrl));
2. Service Worker文件(sw.js,放置在站点根目录)
配置适配跨域视频的缓存策略,监听主线程消息后调用warmStrategyCache完成预热,同时注册路由匹配规则保证后续视频请求直接命中缓存。
// 引入Workbox依赖:如果用npm构建,直接import对应包即可;如果不用构建,可引入Workbox官方CDN资源 importScripts('https://storage.googleapis.com/workbox-cdn/releases/7.0.0/workbox-sw.js'); if (workbox) { // 定义跨域视频专用缓存策略 const contentfulVideoStrategy = new workbox.strategies.CacheFirst({ cacheName: 'contentful-video-cache', fetchOptions: { mode: 'cors', // 跨域请求必须配置,否则返回不透明响应无法正常缓存播放 credentials: 'omit' // Contentful静态资源无需携带cookie }, plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 60, // 最多缓存60个视频,可根据业务调整 maxAgeSeconds: 30 * 24 * 60 * 60, // 缓存有效期30天 purgeOnQuotaError: true // 存储空间不足时自动清理该缓存下的资源 }) ] }); // 注册路由:所有指向Contentful资源域名的请求都走上面定义的缓存策略 // 请将url.origin替换为你自己Contentful空间对应的实际资源域名 workbox.routing.registerRoute( ({url}) => url.origin === 'https://cdn.contentful.com', contentfulVideoStrategy ); // 监听主线程发送的预热消息 self.addEventListener('message', (event) => { if (event.data?.type === 'TRIGGER_VIDEO_WARM') { event.waitUntil( workbox.recipes.warmStrategyCache({ urls: event.data.urls, strategy: contentfulVideoStrategy }) ); } }); }
跨域场景注意事项
- 提前确认Contentful空间的CORS配置已允许你的站点域名访问视频资源,否则跨域请求会被浏览器拦截。
- 视频属于大体积静态资源,不要在页面首屏加载时就触发预热,尽量在用户高概率触发播放的时机调用,避免浪费用户流量。
- 预热完成后,对应视频的请求会直接命中本地缓存,无需等待网络返回,可以实现点击即播的效果。
内容的提问来源于stack exchange,提问作者bobbydp
相关产品推荐
相关产品推荐

