Service Worker 响应时间慢
Service Worker slow response times
在 Windows 和 Android Google Chrome 浏览器中,service worker 的响应时间 Google Chrome =18=] 当您使用带有以下选项的 Cache.match() 函数时,存储在该特定 缓存存储 中的项目数量呈线性增加;
ignoreSearch = true
在多个缓存中划分项目会有所帮助,但这样做并不总是很方便。此外,即使存储的物品数量有少量增加,也会在响应时间上产生很大差异。根据我的测量,缓存中的项目数量每增加十倍,响应时间大约会增加一倍。
我的 question in chromium issue tracker 的官方回答显示该问题是 Chrome 中缓存存储实现的一个已知性能问题,只有当您将 Cache.match()
与 ignoreSearch
一起使用时才会发生参数设置为 true
.
如您所知,ignoreSearch
用于在将请求与缓存中的响应进行匹配时忽略 URL 中的查询参数。 Quote from MDN:
...whether to ignore the query string in the url. For example, if set to
true the ?value=bar part of http://example.com/?value=bar would be ignored
when performing a match.
由于停止使用查询参数匹配并不是很方便,因此我想出了以下解决方法,并将其张贴在这里,希望能为大家节省时间;
// 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
})
);
这很好用,因为它可以正确处理每个请求 和 一个查询参数,同时处理其他请求仍然以闪电般的速度。而且您无需更改应用程序中的任何其他内容。
根据 guy in that bug report,问题与缓存中的项目数有关。我做了一个解决方案并将其发挥到极致,为每个资源提供自己的缓存:
var cachedUrls = [
/* CACHE INJECT FROM GULP */
];
//update the cache
//don't worry Whosebug, 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
并没有真正起作用,因为无论如何我们都必须将它用于所有静态资源,以便我们可以获得缓存命中!
然而,我不仅不喜欢这个 hack,而且它仍然执行得非常慢。
好吧,鉴于这只是我需要 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);
})
);
});
我遇到了同样的问题,之前的方法导致一些请求错误,应该是 ignoreSearch:false。一种对我有用的简单方法是通过使用 url.contains('A') &&[= 将 ignoreSearch:true 简单地应用于某些请求16=] ... 请参见下面的示例:
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) {
...
}
在 Windows 和 Android Google Chrome 浏览器中,service worker 的响应时间 Google Chrome =18=] 当您使用带有以下选项的 Cache.match() 函数时,存储在该特定 缓存存储 中的项目数量呈线性增加;
ignoreSearch = true
在多个缓存中划分项目会有所帮助,但这样做并不总是很方便。此外,即使存储的物品数量有少量增加,也会在响应时间上产生很大差异。根据我的测量,缓存中的项目数量每增加十倍,响应时间大约会增加一倍。
我的 question in chromium issue tracker 的官方回答显示该问题是 Chrome 中缓存存储实现的一个已知性能问题,只有当您将 Cache.match()
与 ignoreSearch
一起使用时才会发生参数设置为 true
.
如您所知,ignoreSearch
用于在将请求与缓存中的响应进行匹配时忽略 URL 中的查询参数。 Quote from MDN:
...whether to ignore the query string in the url. For example, if set to true the ?value=bar part of http://example.com/?value=bar would be ignored when performing a match.
由于停止使用查询参数匹配并不是很方便,因此我想出了以下解决方法,并将其张贴在这里,希望能为大家节省时间;
// 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
})
);
这很好用,因为它可以正确处理每个请求 和 一个查询参数,同时处理其他请求仍然以闪电般的速度。而且您无需更改应用程序中的任何其他内容。
根据 guy in that bug report,问题与缓存中的项目数有关。我做了一个解决方案并将其发挥到极致,为每个资源提供自己的缓存:
var cachedUrls = [
/* CACHE INJECT FROM GULP */
];
//update the cache
//don't worry Whosebug, 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
并没有真正起作用,因为无论如何我们都必须将它用于所有静态资源,以便我们可以获得缓存命中!
然而,我不仅不喜欢这个 hack,而且它仍然执行得非常慢。
好吧,鉴于这只是我需要 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);
})
);
});
我遇到了同样的问题,之前的方法导致一些请求错误,应该是 ignoreSearch:false。一种对我有用的简单方法是通过使用 url.contains('A') &&[= 将 ignoreSearch:true 简单地应用于某些请求16=] ... 请参见下面的示例:
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) {
...
}