andrei1015
andrei1015

Reputation: 63

Service Worker is grabbing everything

I have just recently started fiddling with service workers and am having a situation where no matter what file(s) I tell it to add to the cache, it is adding everything. Now, this would normally mean less work for me toward an offline application, but I am a bit confused. So the cache seems to have two methods of adding requests to it, .add() and .addAll(), with the latter being capable of receiving an array of requests, but even with just .add() with a request hardcoded into it, absolutely all requests seem to end up in the cache.

The code I have is as follows:

    if ('serviceWorker' in navigator) {
        //console.log('CLIENT: service worker registration in progress.');
        navigator.serviceWorker.register('/sw.js').then(function() {
            //console.log('CLIENT: service worker registration complete.');
        }, function() {
            //console.log('CLIENT: service worker registration failure.');
    });
    } else {
        console.log('CLIENT: service worker is not supported.');
    }

... this being in the actual page calling the service worker, and the service worker itself:

var cacheName = 'cache';

self.addEventListener('install', (e) => {
    console.log('[Service Worker] Install');
var appShellFiles = [
];

e.waitUntil(
    caches.open(cacheName).then((cache) => {
          console.log('[Service Worker] Caching all: app shell and content');
      return cache.add('assets/images/boy.svg').then(function() {
        // requests have been added to the cache
        console.log('added')
      });
    })
  );
});

self.addEventListener('fetch', (e) => {
    e.respondWith(
      caches.match(e.request).then((r) => {
            console.log('[Service Worker] Fetching resource: '+e.request.url);
        return r || fetch(e.request).then((response) => {
                  return caches.open(cacheName).then((cache) => {
            console.log('[Service Worker] Caching new resource: '+e.request.url);
            cache.put(e.request, response.clone());
            return response;
          });
        });
      })
    );
  });

self.addEventListener('activate', (e) => {
    e.waitUntil(
      caches.keys().then((keyList) => {
            return Promise.all(keyList.map((key) => {
          if(key !== cacheName) {
            return caches.delete(key);
          }
        }));
      })
    );
  });

... but in here .add('assets/images/boy.svg') used to be .addAll(appShellFiles), which itself used to contain individual files, but seemed to ignore the list and still cache everything. What am I missing?

Upvotes: 0

Views: 776

Answers (1)

pate
pate

Reputation: 5263

It's very simple. Look at this code:

self.addEventListener('fetch', (e) => {
    e.respondWith(
      caches.match(e.request).then((r) => {
            console.log('[Service Worker] Fetching resource: '+e.request.url);
        return r || fetch(e.request).then((response) => {
                  return caches.open(cacheName).then((cache) => {
            console.log('[Service Worker] Caching new resource: '+e.request.url);
            cache.put(e.request, response.clone());
            return response;
          });
        });
      })
    );
  });

It saves everything in the cache dynamically/on the fly/automatically. Your code is correct – initially it only caches the one file you mentioned. But immediately as the app starts up, the SW caches everything.

Another way to look at this problem of "caching everything": caching everything doesn't even mean anything. The browser has no way of knowing what that "everything" means for a particular site. It could be 4 or 4000 assets. Once this is realized, it is only a matter of finding the correct piece of code.

Upvotes: 1

Related Questions