2
  • 缓存来自应用程序的所有请求,而无需明确指定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;
        });
    }));
});

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

我还尝试将 cache_name 修改为cache-v2from cache-v1(以便存在 sw 二进制差异并更新 sw 并且可以清除旧缓存),并cache-v1activate事件中清除。但它带来了新的问题,即两个 Service Worker 在同一时间同时运行Registration ID。有关这方面的更多信息,请参见另一个 SO 问题:如何阻止年长的服务人员?

4

1 回答 1

6

两个同时运行的服务人员在技术上不是问题——它按设计工作。(请参阅我对如何停止旧版服务人员的回答? )确保关闭其他可能激活旧版服务人员的选项卡。

您在这里遇到了不同缓存与网络场景之间不可避免的权衡。如果您尚未通读离线说明书,那么在尝试确定哪种缓存策略最适合您的特定资源时,这是一个很好的起点。

于 2015-01-21T22:03:27.630 回答