【问题标题】:Service Worker and transparent cache updatesService Worker 和透明缓存更新
【发布时间】:2016-02-09 00:19:11
【问题描述】:

我正在尝试为一个简单但旧的 Django Web 应用程序安装一个 ServiceWorker。我开始使用示例read-through caching example from the Chrome team

这很好用,但并不理想,因为如果需要,我想更新缓存。根据阅读此处所有其他服务人员的答案,有两种推荐的方法来做到这一点。

  1. 使用一些服务器端逻辑来了解您显示的内容何时更新,然后更新您的服务工作者以更改预缓存的内容。例如,这就是 sw-precache 所做的。

  2. 只要您依赖更新的资源,只需更新 Service Worker JS 文件中的缓存版本(请参阅上面缓存示例中 JS 文件中的 cmets)。

对我来说都不是很好的解决方案。首先,这是一个愚蠢的遗留应用程序。我没有 sw-precache 依赖的应用程序堆栈。其次,其他人更新将要显示的数据(它基本上是带有详细信息页面的事物列表)。

我想尝试一下 Jake Archibald 在他的 offline cookbook 中建议的“使用缓存,但从网络更新缓存”,但我无法让它发挥作用。

我最初的想法是我应该能够在我的 service worker 中返回缓存的版本,但是如果网络可用,我会排队一个更新缓存的函数。例如,在 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;

但这不起作用。页面卡住加载。

上面的代码有什么问题?实现目标设计的正确方法是什么?

【问题讨论】:

    标签: service-worker


    【解决方案1】:

    听起来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;
          });
        })
      );
    });
    

    【讨论】:

    • 嗯..不完全是,因为,如果我没记错的话,这仍然会首先访问网络。因此,对于慢速网络,需要很长时间然后返回网络响应(这很可能与缓存的响应相同)。这将离线,但不会很快。
    • 不,缓存响应不等待网络请求,所以如果它被缓存,你会得到即时响应
    • aah .. 所以如果响应为空,那么 fetchPromise 就解决了吗?
    • 从技术上讲,它是未定义的,而不是 null,但是是的。好吧,fetchPromise 总是会解析,但浏览器不会等待它显示缓存的内容。
    • 抱歉耽搁了!我很兴奋并立即开始玩它。
    【解决方案2】:

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

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

    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

    【讨论】:

      猜你喜欢
      • 2019-10-08
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-27
      相关资源
      最近更新 更多