Javascript PWA-空服务工作者预缓存运行时

Javascript PWA-空服务工作者预缓存运行时,javascript,progressive-web-apps,service-worker,sw-precache,Javascript,Progressive Web Apps,Service Worker,Sw Precache,我正在开发一个基于音频的PWA,由于我不熟悉这项技术,我对服务人员中的缓存管理和失效有一些疑问 应用程序需要脱机工作,我使用SW precache介绍了这一点 我唯一的疑问是数据量:在经验中有5个用例场景。每个场景都有大约30MB的音频内容,这意味着precache总共有150MB以上的所有图像、js和css 我知道这超出了某些浏览器的限制(se this和this) 一般来说,您必须注意存储大小,这也取决于用户的设备在磁盘上的可用空间 这就是我所想的:由于在一个场景和另一个场景之间,用户会停在

我正在开发一个基于音频的PWA,由于我不熟悉这项技术,我对服务人员中的缓存管理和失效有一些疑问

应用程序需要脱机工作,我使用SW precache介绍了这一点

我唯一的疑问是数据量:在经验中有5个用例场景。每个场景都有大约30MB的音频内容,这意味着precache总共有150MB以上的所有图像、js和css

我知道这超出了某些浏览器的限制(se this和this) 一般来说,您必须注意存储大小,这也取决于用户的设备在磁盘上的可用空间

这就是我所想的:由于在一个场景和另一个场景之间,用户会停在一张有WiFi连接的桌子旁,我的想法是在用户操作后清空缓存运行时(如按下按钮),并用新内容替换它。 这样我一次只存储一个场景,也就是说~35MB,一个合理的大小

你认为这是个好办法吗? 实现这一点的最佳方式是什么

以下是我当前的代码:

service worker.js

const PRECACHE='PRECACHE-test-v1';
//我们始终希望缓存的本地资源列表。
const PRECACHE_URL=[
'/',
“/audio/scenario1.mp3”,
“/audio/scenario2.mp3”,
“/audio/scenario3.mp3”,
“/audio/scenario4.mp3”,
“/audio/scenario5.mp3”,
“/css/style.css”,
“/js/bundle.js”,
“/img/favicon.png”,
“/img/logo.png”,
“/img/image1.png”,
“/img/image2.png”,
“/img/image3.png”,
“/img/image4.png”,
“/img/image5.png”,
];
//永远不要缓存这些资源
const TO_SKIP=[/*暂时为空*/];
//安装处理程序负责预编译我们始终需要的资源。
self.addEventListener('install',事件=>{
const now=新日期();
log(`PWA服务工作者安装-::${now}::`);
event.waitUntil(caches.open(PRECACHE).then(cache=>{
返回cache.addAll(预缓存URL)。然后(()=>{
自我skipWaiting();
});
}));
});
//激活处理程序负责清理旧缓存。
self.addEventListener('activate',event=>{
const now=新日期();
log(`PWA服务工作者激活-::${now}::`);
const currentCaches=[PRECACHE];
event.waitill(
caches.keys().then(cacheNames=>{
返回cacheNames.filter(cacheName=>!currentCaches.includes(cacheName));
})。然后(cachesToDelete=>{
返回Promise.all(cachesToDelete.map(cacheToDelete=>{
返回caches.delete(cacheToDelete);
}));
}).然后(()=>self.clients.claim())
);
});
//fetch处理程序为来自缓存的相同源资源提供响应。
self.addEventListener('fetch',event=>{
//跳过跨源请求,如谷歌分析和其他提供的URL。
if(event.request.url.startsWith(self.location.origin)和&TO_SKIP.every(url=>!event.request.url.includes(url))){
事件响应(
caches.match(event.request).then(resp=>{
返回resp | | fetch(event.request)。然后返回(response=>{
返回缓存。打开(预缓存)。然后(缓存=>{
cache.put(event.request,response.clone());
返回响应;
});
});
})
);
}
});
index.js

if(导航器中的“serviceWorker”){
navigator.serviceWorker.register('/sw.js')。然后(registration=>{
console.log('注册成功,作用域为:',Registration.scope);
}).catch(错误=>{
console.log('服务工作者注册失败,错误:',错误);
});
}
谢谢你抽出时间,
弗朗西斯科

嗯。。您可以提供一个按钮
Save for offline
,而不是预存5个视频,这样用户就可以只保存他以后要脱机观看的视频:

let videoUrl = url to that video:
button.addEventListener('click', function(event) {
  event.preventDefault();
  caches.open("myVideoCache").then(function(cache) {
    fetch(videoUrl)
     .then(function(video) {
        cache.add(video);
     });
  });
});
删除您需要打开缓存并将其删除的1个条目。传递存储的路径

caches.open('myVideoCache').then(function(cache) {
  cache.delete('/path/to/audio.mp4').then(function(response) {
    console.log("entry deleted");
  });
})

您可以在这里找到更多详细信息:

Hi@Ifaruki,谢谢您的回答!这是一个很好的方法,但是如果用户保存第三个或第四个内容(实际上是音频而不是视频,但不管怎样)时,缓存大小超过了限制怎么办?是否有办法从缓存中定位并删除旧内容?@FrancescoCretti是的,您可以从缓存中删除单个入口,您需要传递该缓存资产/文件的url。如果使用chrome,请按F12。然后转到应用程序。然后转到缓存,单击缓存存储,查看您的
myVideoCache
或您选择的名称。然后您会看到行
名称
,这是您需要在delete方法中传递的URL