Service Worker和透明缓存更新

5
我正在尝试为一个简单但古老的Django Web应用程序安装ServiceWorker。我开始使用Chrome团队的读取缓存示例进行工作。
这很有效,但并不理想,因为我想在需要时更新缓存。根据阅读所有其他服务工作者答案,有两种推荐的方法可以做到这一点。
  1. 使用一些服务器端逻辑来知道您显示的内容何时更新,然后更新您的服务工作者以更改预缓存内容。例如,这就是sw-precache所做的。

  2. 只需在服务工作者JS文件中更新缓存版本(请参见上面缓存示例中的JS文件中的注释),每当您依赖的资源更新时。

对我来说,两者都不是很好的解决方案。首先,这是一个愚蠢的遗留应用程序。我没有sw-precache依赖的应用程序堆栈。其次,其他人会更新将显示的数据(基本上是带有详细页面的事物列表)。
我想尝试Jake Archibald在他的离线食谱中建议的“使用缓存,但从网络更新缓存”的方法,但我无法使它正常工作。我的最初想法是,在服务工作者中返回缓存版本,但若有网络可用则排队一个更新缓存的函数。例如,在fetch事件监听器中实现如下:
// If there is an entry in cache, return it after queueing an update
console.log(' Found response in cache:', response);
setTimeout(function(request, cache){
    fetch(request).then(function(response){
        if (response.status < 400 && response.type == 'basic') {
            console.log("putting a new response into cache");
            cache.put(request, response);
        }   
    })  
},10, request.clone(), cache);

return response;

但是这样做不起作用。页面卡在加载中。

上面的代码有什么问题?如何才能达到我的目标设计?

2个回答

8

听起来像是你正在寻找的内容非常接近 https://jakearchibald.com/2014/offline-cookbook/#stale-while-revalidate

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.open('mysite-dynamic').then(function(cache) {
      return cache.match(event.request).then(function(response) {
        var fetchPromise = fetch(event.request).then(function(networkResponse) {
          // if we got a response from the cache, update the cache
          if (response) {
            cache.put(event.request, networkResponse.clone());
          }
          return networkResponse;
        });

        // respond from the cache, or the network
        return response || fetchPromise;
      });
    })
  );
});

嗯...不太对,因为如果我没记错的话,这仍然会首先访问网络。所以,对于慢速网络,它将需要很长时间,然后返回网络响应(很可能与缓存响应相同)。这将是离线的,但不快速。 - devd
不,缓存响应不会等待网络请求,因此如果已经缓存,您将立即获得响应。 - JaffaTheCake
啊哈...所以只有在响应为空时,fetchPromise才会被解决? - devd
从技术上讲,它是未定义的而不是空值,但是是的。fetchPromise将始终解析,但浏览器不会等待它显示缓存的内容。 - JaffaTheCake
抱歉耽搁了!我太兴奋了,马上开始玩它了。 - devd
您可以立即激活新的服务工作者,请参见此链接 - Akshay Gundewar

0

在页面重新加载时,您可以使用新版本刷新您的服务工作者,同时旧版本将处理请求。

一旦所有操作完成且没有页面使用旧的服务工作者,它将使用更新的服务工作者版本。

this.addEventListener('fetch', function(event){
    event.responseWith(
        caches.match(event.request).then(function(response){
            return response || fetch(event.request).then(function(resp){
                return caches.open('v1').then(function(cache){
                    cache.put(event.request, resp.clone());
                    return resp;
                })
            }).catch(function() {
                return caches.match('/sw/images/myLittleVader.jpg');
            });
        })
    )
});

我建议你点击下面的链接,了解详细的功能。

https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接