在Windows和Android Google Chrome浏览器中(还未测试其他浏览器),当您使用具有以下选项的Cache.match()函数时,服务工作线程响应时间与特定缓存存储中存储的项目数量呈线性增长。
ignoreSearch = true
将项目分配到多个缓存中有所帮助,但不总是方便的。而且,即使存储的项目数量增加了很少一部分,在响应时间上也会有很大的差异。根据我的测量,每当缓存中的项目数量增加十倍时,响应时间大约会增加一倍。
ignoreSearch = true
将项目分配到多个缓存中有所帮助,但不总是方便的。而且,即使存储的项目数量增加了很少一部分,在响应时间上也会有很大的差异。根据我的测量,每当缓存中的项目数量增加十倍时,响应时间大约会增加一倍。
官方回答我的Chromium问题追踪器中的问题揭示了Cache Storage在Chrome中实现性能存在已知问题,只有当您使用Cache.match()
并将ignoreSearch
参数设置为true
时才会发生该问题。
如您所知,ignoreSearch
用于在匹配请求与缓存响应时忽略URL中的查询参数。MDN上的引用:
...是否要忽略url中的查询字符串。例如,如果将其设置为true,则在进行匹配时,http://example.com/?value=bar中的?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
})
);
这非常有效,因为它可以正确地处理每个带有查询参数的请求,并仍然以惊人的速度处理其他请求。您无需更改应用程序中的任何其他内容。
我曾经遇到同样的问题,之前的解决方法会导致一些请求出现错误,这些请求应该是 ignoreSearch:false。一个对我有效的简单方法是通过使用 url.contains('A') && 将 ignoreSearch:true 应用于特定的请求。参见下面的示例:
self.addEventListener("fetch", function(event) {
var ignore
if(event.request.url.includes('A') && event.request.url.includes('B') && event.request.url.includes('C')){
ignore = true
}else{
ignore = false
}
event.respondWith(
caches.match(event.request,{
ignoreSearch:ignore,
})
.then(function(cached) {
...
}
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);
});
});
);
}
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);
})
);
});