2017-01-20 96 views
4

在Windows和Android的谷歌Chrome浏览器,(没有测试为别人还)响应时间从服务工作者线性增加到存储在特定缓存存储当您使用项目数具有以下选项的功能Cache.match();服务人员响应时间慢

ignoreSearch = true 

在多个缓存中划分项有助于但并不总是方便。此外,即使存储物品的数量增加也会使响应时间有很大差异。根据我的测量响应时间几乎翻了一倍,每十倍于缓存中的项目的数量增加。

回答

6

官方回答我question in chromium issue tracker揭示问题与Chrome浏览器的缓存存储实现一个已知的性能问题,当您使用Cache.match()ignoreSearch参数设置为true只发生。

正如你可能知道ignoreSearch用于忽略查询参数的URL,同时匹配针对缓存响应该请求。 Quote from MDN

...是否忽略url中的查询字符串。例如,如果设置为 真?的http://foo.com/?value=bar值=酒吧部分执行匹配时将被忽略 。

由于停止使用查询参数匹配并不方便,因此我提出了以下解决方法,并且在此发布它,希望能为其节省时间;

// if the request has query parameters, `hasQuery` will be set to `true` 
var hasQuery = event.request.url.indexOf('?') != -1; 

event.respondWith(
    caches.match(event.request, { 
     // ignore query section of the URL based on our variable 
     ignoreSearch: hasQuery, 
    }) 
    .then(function(response) { 
     // handle the response 
    }) 
); 

这个伟大的工程,因为它正确地处理每一个请求的查询参数,同时还以迅雷不及掩耳的速度处理等。而且您不必在应用程序中更改其他任何内容。

+0

优秀!!!希望你能完成event.respondWith()代码。 –

+1

@MahmoudAliKassem当然,在这里你去。将代码片段更新为完整的工作代码。干杯! –

0

按照guy in that bug report,这个问题被拴在高速缓存中的项目数。我做了一个解决方案,它走上了极致,让每个资源它自己的缓存:

var cachedUrls = [ 
    /* CACHE INJECT FROM GULP */ 
]; 

//update the cache 
//don't worry StackOverflow, I call this only when the site tells the SW to update 
function fetchCache() { 
    return Promise.all(
     //for all urls 
     cachedUrls.map(function(url) { 
      //add a cache 
      return caches.open('resource:'url).then(function(cache) { 
       //add the url 
       return cache.add(url); 
      }); 
     }); 
    ); 
} 

在我们这里,也有静态的资源,设置较高的高速缓存到期服务的项目,我们使用的查询参数(存储库版本号,注入html)只能作为管理[浏览器]缓存的一种方式。
它并没有真正的工作使用您的解决方案有选择地使用ignoreSearch,因为我们不得不反正所有使用它的静态资源,使我们可以得到高速缓存命中!

但是,我不仅不喜欢这种黑客行为,而且它还是仍然表现非常缓慢。


好了,所以,考虑到这只是我需要ignoreSearch资源的一组特定的,我决定走了不同的路线;
刚刚从手动URL请求删除,而不是依靠ignoreSearch的参数。

self.addEventListener('fetch', function(event) { 
    //find urls that only have numbers as parameters 
    //yours will obviously differ, my queries to ignore were just repo revisions 
    var shaved = event.request.url.match(/^([^?]*)[?]\d+$/); 
    //extract the url without the query 
    shaved = shaved && shaved[1]; 

    event.respondWith(
     //try to get the url from the cache. 
     //if this is a resource, use the shaved url, 
     //otherwise use the original request 
     //(I assume it [can] contain post-data and stuff) 
     caches.match(shaved || event.request).then(function(response) { 
      //respond 
      return response || fetch(event.request); 
     }) 
    ); 
});