run_the_race
run_the_race

Reputation: 2408

Does a service worker allow one to simply use long expiration headers on static assets?

Say I have a service worker that populates the cache with the following working code when its activated:

async function install() {
    console.debug("SW: Installing ...");
    const cache = await caches.open(CACHE_VERSION);
    await cache.addAll(CACHE_ASSETS);
    console.log("SW: Installed");
}
async function handleInstall(event) {
    event.waitUntil(install());
}
self.addEventListener("install", handleInstall);

When performs cache.addAll(), will the browser use its own internal cache, or will it always download the content from the site? This is important, because it one creates a new service worker release, and there are new static assets, the old version maybe be cached by the service worker.

If not then I guess one still has to do named hashed/versioned static assets. Something I was hoping service workers would make none applicable.

Upvotes: 0

Views: 94

Answers (1)

Jeff Posnick
Jeff Posnick

Reputation: 56114

cache.addAll()'s behavior is described in the service worker specification, but here's a more concise summary:

  1. For each item in the parameter array, if it's a string and not a Request, construct a new Request using that string as input.
  2. Perform fetch() on each request and get a response.
  3. As long as the response has an ok status, call cache.put() to add the response to the cache, using the request as the key.

To answer your question, the most relevant step is 1., as that determines what kind of Request is passed to fetch(). If you just pass in a string, then there are a lot of defaults that will be used when implicitly constructing the Request. If you want more control over what's fetch()ed, then you should explicitly create a Request yourself and pass that to cache.addAll() instead of passing in strings.

For instance, this is how you'd explicitly set the cache mode on all the requests to 'reload', which always skip the browser's normal HTTP cache and go against the network for a response:

// Define your list of URLs somewhere...
const URLS = ['/one.css', '/two.js', '/three.js', '...'];

// Later...
const requests = URLS.map((url) => new Request(url, {cache: 'reload'}));
await cache.addAll(requests);

Upvotes: 2

Related Questions