2017-01-20 142 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); 
     }) 
    ); 
});