服务工作者响应时间慢

问题描述 投票:5回答:2

在Windows和Android Google Chrome浏览器中,(尚未对其他人进行测试)当您使用带有以下选项的Cache.match()函数时,服务工作者的响应时间会线性增加到存储在该特定缓存存储中的项目数量;

ignoreSearch = true

在多个缓存中划分项目有助于但并非总是方便。此外,即使存储的项目少量增加也会使响应时间产生很大差异。根据我的测量结果,缓存中项目数量每增加十倍,响应时间大约翻倍。

google-chrome service-worker progressive-web-apps
2个回答
9
投票

对我的question in chromium issue tracker的正式回答显示,问题是Chrome中缓存存储实现的一个已知性能问题,只有当您使用Cache.match()并将ignoreSearch参数设置为true时才会出现此问题。

您可能知道ignoreSearch用于忽略URL中的查询参数,同时将请求与缓存中的响应进行匹配。 Quote from MDN

...是否忽略url中的查询字符串。例如,如果设置为true,则执行匹配时将忽略http://foo.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
    })
);

这非常有用,因为它可以正确地处理每个请求并使用查询参数,同时仍能以闪电般的速度处而且您不必在应用程序中更改任何其他内容。


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的一组特定资源,我决定采取不同的路线; 只需手动删除网址请求中的参数,而不是依赖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);
        })
    );
});
© www.soinside.com 2019 - 2024. All rights reserved.