0

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

应用程序需要离线工作,我使用 SW 预缓​​存进行了介绍。

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

我知道这超出了某些浏览器的限制(参见 this question和 this article),通常您必须注意存储大小,这也取决于用户设备的磁盘可用空间。

所以这就是我的想法:由于在一种情况和另一种情况之间,用户会在有 WiFi 连接的办公桌前停下来,我的想法是在用户操作(如按下按钮)后清空缓存运行时,并将其替换为新内容. 这样我一次只能存储一个场景,这意味着〜35MB,一个合理的大小。

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

这是我当前的代码:

service-worker.js

 const PRECACHE = 'precache-test-v1';

 // A list of local resources we always want to be cached.
 const PRECACHE_URLS = [
   '/',
   '/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',
 ];

 // never cache these resources
 const TO_SKIP = [/* empty for now */];

// The install handler takes care of precaching the resources we always need.
self.addEventListener('install', event => {
  const now = new Date();
  console.log(`PWA Service Worker installing - :: ${now} ::`);
  event.waitUntil(caches.open(PRECACHE).then(cache => {
    return cache.addAll(PRECACHE_URLS).then(() => {
      self.skipWaiting();
    });
  }));
});

// The activate handler takes care of cleaning up old caches.
self.addEventListener('activate', event => {
  const now = new Date();
  console.log(`PWA Service Worker activating - :: ${now} ::`);
  const currentCaches = [PRECACHE];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
    }).then(cachesToDelete => {
      return Promise.all(cachesToDelete.map(cacheToDelete => {
        return caches.delete(cacheToDelete);
      }));
    }).then(() => self.clients.claim())
  );
});

// The fetch handler serves responses for same-origin resources from a cache.
self.addEventListener('fetch', event => {
  // Skip cross-origin requests, like those for Google Analytics and the other provided urls.
  if (event.request.url.startsWith(self.location.origin) && TO_SKIP.every(url => !event.request.url.includes(url))) {
    event.respondWith(
      caches.match(event.request).then(resp => {
        return resp || fetch(event.request).then(response => {
          return caches.open(PRECACHE).then(cache => {
            cache.put(event.request, response.clone());
            return response;
          });
        });
      })
    );
  }
});

index.js

if ('serviceWorker' in navigator) {
   navigator.serviceWorker.register('/sw.js').then(registration => {
     console.log('Registration successful, scope is:', registration.scope);
   }).catch(error => {
     console.log('Service worker registration failed, error:', error);
   });
}

谢谢你的时间,弗朗西斯科

4

1 回答 1

1

嗯..而不是预先缓存 5 个视频,您可以提供一个按钮Save for offline,以便用户可以只保存他想稍后离线观看的视频:

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");
  });
})

您可以在此处找到更多详细信息:https ://developers.google.com/web/ilt/pwa/caching-files-with-service-worker

于 2020-06-27T12:40:17.733 回答