【问题标题】:How and When should we write to cache in Service Workers?我们应该如何以及何时写入 Service Worker 中的缓存?
【发布时间】:2015-01-21 14:43:03
【问题描述】:
  • 在不明确指定urlsToCache 的情况下缓存来自应用的所有请求。所以我会缓存fetch事件下的东西。
  • 响应来自缓存的请求。
  • 获取成功时更新缓存。

最初,

this.addEventListener('fetch', function(event) {
    var fetchReq = event.request.clone(),
        cacheReq = event.request.clone();
    event.respondWith(fetch(fetchReq).then(function(response) {
        var resp = response.clone();
        caches.open(CACHE_NAME).then(function(cache) {
            req = event.request.clone();
            cache.put(req, resp);
        });
        return response;
    }).catch(function() {
        return caches.match(cacheReq);
    }));
});

离线情况处理得很好。但这里的问题是连接速度慢。用户必须等到 fetch 超时或抛出错误才能从缓存中获取响应。

self.addEventListener('fetch', function(event) {
    var cacheRequest = event.request.clone();
    event.respondWith(caches.match(cacheRequest).then(function(response) {
        if(response) return response;
        var fetchRequest = event.request.clone();
        return fetch(fetchRequest).then(function(response) {
            var responseToCache = response.clone();
            caches.open(cache_name).then(function(cache) {
                var cacheSaveRequest = event.request.clone();
                cache.put(cacheSaveRequest, responseToCache);
            });
            return response;
        });
    }));
});

在缓存优先的情况下,提供的响应很好。但是这里的问题是当代码更新时。当通过 sw 提供的/public/main.css 更新时,在页面重新加载时仅提供缓存,不提供更新的内容。

我还尝试将 cache_name 从 cache-v1 修改为 cache-v2(以便存在 sw 二进制差异并且更新 sw 并且可以清除旧缓存),并在 activate 事件中清除 cache-v1。但它引发了新的问题,即两个服务人员同时在同一个Registration ID 下运行。有关这方面的更多信息,请参见另一个 SO 问题:How to stop older service workers?

【问题讨论】:

  • 不清楚您的问题是关于缓存策略(缓存优先与网络优先)(标题)还是更新时从缓存提供内容的问题(文本)。

标签: javascript caching service-worker


【解决方案1】:

同时运行的两个 Service Worker 在技术上不是问题——它按设计工作。 (请参阅我对How to stop older service workers? 的回答)确保关闭其他可能激活了旧版 Service Worker 的选项卡。

您在这里遇到了不同缓存与网络场景之间不可避免的权衡。如果您尚未通读 the offline cookbook,这是一个很好的起点,可帮助您确定哪种缓存策略最适合您的特定资源。

【讨论】:

  • tradeoffs between cache vs network scenarios - 完全正确!。顺便说一句,是否有任何建议添加缓存 TTL。我正在改变 Response 克隆。喜欢response.TTL = new Date() + ttl;我认为这是一种不好的使用方式。
  • 我没有关于缓存 TTL 的具体建议。还没有尝试过。查看github.com/jeffposnick/sw-precache 的示例,该示例使用文件哈希作为识别资源何时更新的一种方式,这是一种不同的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多