【问题标题】:How to control if PWA uses cached version or fetches latest version?如何控制 PWA 是使用缓存版本还是获取最新版本?
【发布时间】:2019-01-23 07:51:57
【问题描述】:

我已经从 Android 上的 Chrome 和 Firefox 以及 iOS 上的 Safari 安装了我的 PWA。当我在网站上更新我的代码时,我看到 PWA 在使用旧缓存版本和最新版本方面的行为完全不同 - Firefox 创建的 PWA 似乎需要大约 2-3 次终止和重新启动 PWA,Chrome 需要 5 -6,如果不删除 PWA 并从浏览器重新添加到主屏幕,我无法让基于 Safari 的 PWA 开始显示最新版本。

是否有规范定义获取较新的非缓存版本的条件?经过大量阅读,我禁用了我的服务工作者的注册,这应该使 PWA 仅网络(没有服务工作者缓存),但我继续在 PWA 中提供旧版本的站点。一个普通的浏览器窗口似乎也需要多次深度刷新才能获得新版本,所以我认为除了 service worker 之外还有其他东西决定了这一点?

【问题讨论】:

  • 我认为问题更多的是你如何为你的 PWA 提供服务,它是否首先是缓存,如果是,那么它将响应来自缓存文件的请求,而不是从网络获取它
  • 您能否详细说明您的意思?

标签: progressive-web-apps


【解决方案1】:

考虑以下代码。我将把它分成几部分:

   self.addEventListener('fetch', function(event) {
  event.respondWith(


    caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }

        return fetch(event.request).then(
          function(response) {
            // Check if we received a valid response
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }

            // IMPORTANT: Clone the response. A response is a stream
            // and because we want the browser to consume the response
            // as well as the cache consuming the response, we need
            // to clone it so we have two streams.
            var responseToCache = response.clone();

            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });

            return response;
          }
        );
      })
    );
});

这里使用的是缓存优先策略,每当你重新加载页面时,就会触发一个 fetch 事件。

caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }

首先它检查所需的请求是否在缓存中可用,如果是则它将返回响应并且不会从网络获取。

 return fetch(event.request).then(
          function(response) {
            // Check if we received a valid response
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }

            // IMPORTANT: Clone the response. A response is a stream
            // and because we want the browser to consume the response
            // as well as the cache consuming the response, we need
            // to clone it so we have two streams.
            var responseToCache = response.clone();

            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });

            return response;
          }
        );
      })
    );

现在,如果文件不存在于缓存中,则此块会进入网络收集所需的文件,然后对其进行响应,并将其保存到缓存中以供进一步使用。

假设您有一个文件 sample.html 并且它已被缓存,现在您对文件的代码进行了一些更改,但这些更改不会在您的浏览器上看到,因为它会看到 sample.html(旧) 已经存在于缓存中并用它来响应。

【讨论】:

  • 谢谢,但如果我没有注册 Service Worker(如上所述),那么它应该总是进行网络获取,而不是缓存?
  • 你可能会使用 window.loaction.reload(true) stackoverflow.com/questions/5721704/… 我建议你使用 Service Worker,因为它们适用于 PWA
【解决方案2】:

关于 SW 和 PWA 的一些通用注意事项: 注册 Service Worker (SW) 后,您必须取消注册以确保获得最新/更新版本,您可以在 Service Worker 下的应用程序选项卡中执行此操作

然后

确保您获得 PWA 的最新/更新版本。除此之外,您还可以做些什么,您可以更改缓存存储的对象名称,如下所示: .

只要您保持对象名称相同并且不注销软件并清除缓存存储,您将不得不刷新您的网站。如果您按住浏览器的刷新按钮几秒钟,还有硬重新加载/清除缓存和硬重新加载选项,但在您取消注册服务工作者之前它仍然不起作用。因此,简而言之,取消注册 SW 并手动清除缓存存储或更改缓存存储对象的名称就可以解决问题。像任何其他技术/资产一样,有利也有弊。这是 PWA 的缺点之一,如果我们没有正确使用它,您的客户将永远无法获得最新版本,或者他获得它的时间可能为时已晚。干杯:)

【讨论】:

    猜你喜欢
    • 2021-12-29
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    • 2022-06-28
    • 1970-01-01
    相关资源
    最近更新 更多