Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service Worker slow response times

In Windows and Android Google Chrome browser, (haven't tested for others yet) response time from a service worker increases linearly to number of items stored in that specific cache storage when you use Cache.match() function with following option;

ignoreSearch = true

Dividing items in multiple caches helps but not always convenient to do so. Plus even a small amount of increase in items stored makes a lot of difference in response times. According to my measurements response time is roughly doubled for every tenfold increase in number of items in the cache.

like image 950
Umur Karagöz Avatar asked Jan 20 '17 07:01

Umur Karagöz


2 Answers

Official answer to my question in chromium issue tracker reveals that the problem is a known performance issue with Cache Storage implementation in Chrome which only happens when you use Cache.match() with ignoreSearch parameter set to true.

As you might know ignoreSearch is used to disregard query parameters in URL while matching the request against responses in cache. 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.

Since it is not really convenient to stop using query parameter match, I have come up with following workaround, and I am posting it here in hopes of it will save time for someone;

// 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
  })
);

This works great because it handles every request with a query parameter correctly while handling others still at lightning speed. And you do not have to change anything else in your application.

like image 186
Umur Karagöz Avatar answered Nov 18 '22 11:11

Umur Karagöz


I had the same issue, and previous approaches caused some errors with requests that should be ignoreSearch:false. An easy approach that worked for me was to simply apply ignoreSearch:true to a certain requests by using url.contains('A') && ... See example below:

    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) {
            ...
           }
like image 44
marcos_xv Avatar answered Nov 18 '22 10:11

marcos_xv