JGrassini
JGrassini

Reputation: 101

Does a fetch call from a ServiceWorker use the regular browser cache

I'm wondering if a fetch call in a ServiceWorker uses the normal browser cache or bypasses it and sends the request always to the server

For example. Does the fetch call on line 5 first look in the browser cache or not.

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.open('mysite-dynamic').then(function(cache) {
      return cache.match(event.request).then(function (response) {
        return response || fetch(event.request).then(function(response) {
          cache.put(event.request, response.clone());
          return response;
        });
      });
    })
  );
});

Upvotes: 3

Views: 378

Answers (1)

pate
pate

Reputation: 5253

That's a good question. And the answer is: fetch inside the SW works just like fetch in the browser context. This means that the browser's HTTP cache is checked and only after that the network is consulted. Fetch from the SW doesn't bypass the HTTP cache.

This comes with a potential for a race condition if you're not careful with how you name your static assets.

Example:

  1. asset.css is served from the server with max-age: 1y
  2. after the first request for it the browser's HTTP cache has it
  3. now the file's contents are updated; the file is different but the name is still the same (asset.css)
  4. any fetch event to the file, asset.css, is now served from the HTTP cache and any logic that the SW implements to check the file from the server is actually leading to getting the initial file from step 1 from the HTTP cache
  5. at this point the file on the server could be incompatible with some other files that are cached and something breaks

Mitigations: 1. Always change the name of the static asset when the content changes 2. Include a query string (do not ask for asset.css, but for asset.css?timestamporsomething)

Required very good reading: https://jakearchibald.com/2016/caching-best-practices/

Upvotes: 1

Related Questions