`cache.addAll()` receives a list of URLs, and fetches each of them from the network.

It returns a promise that only resolves if all the URLs were added to the cache successfully.

`cache.adderall(`⚡`)` receives a list of URLs, then the lazy bastard looks for them in existing caches, only fetching them from the network if it has to.

It returns a promise that only resolves if all the URLs were added to the cache successfully.

### What does `cache.adderall(`⚡`)` do?

When we install a new service worker, it is common practice to use `cache.addAll()` to cache all the URLs our web app needs. Then, when we make any change to the service worker, or change the list of files it needs to cache, the install event runs again and fetches every single file again… This can be terribly inefficient and wasteful.

`cache.adderall(`⚡`)` is very much like the browser's native `cache.addAll()`. The only difference is that when you call it, `cache.adderall(`⚡`)` first looks for the files you are trying to cache in the user's existing caches. If any of these files are found, they will be copied over to the new cache, so that your service worker only needs to download new files. Any file that isn't already cached will be fetched as usual using the native `cache.addAll()`.

This saves bandwidth, speeds up your service worker installation, and saves your users from downloading the same files over and over again, every time your service worker changes.

### Using `cache.adderall(`⚡`)`

Once you've imported `cache.adderall(`⚡`)` into your service worker, calling `cache.adderall(`⚡`)` is very much like calling `cache.addAll()`. The only difference is that instead of calling `addAll()` on a cache object and passing it an array of URLs, you call `adderall.addAll()` passing it the cache object followed by the array of URLs.

    // In your service worker
    importScripts('js/cache.adderall.js');

    var STATIC_FILES = [
      'video/cache.adderall.demo.mp4',
      '/bootstrap/3.3.7/css/bootstrap.min.css',
      '/js/2.6.0/annyang.min.js'
    ];

    self.addEventListener('install', event => {
      event.waitUntil(
        caches.open('cache-v1').then(cache =>
          adderall.addAll(cache, STATIC_FILES)
        )
      );
    });

    // In your service worker

    var STATIC_FILES = [
      'video/cache.adderall.demo.mp4',
      '/bootstrap/3.3.7/css/bootstrap.min.css',
      '/js/2.6.0/annyang.min.js'
    ];

    self.addEventListener('install', event => {
      event.waitUntil(
        caches.open('cache-v1').then(cache =>
             cache.addAll(STATIC_FILES)
        )
      );
    });

When the service worker above first runs in your user's service worker, it will behave exactly like `cache.addAll()`. But let's say you then decide to add a 4th file to the `STATIC_FILES` array, this is where `cache.adderall(`⚡`)` shines. Where `cache.addAll()` would download every file again, `adderall.addAll()` only downloads the new file, and copies existing files from the old cache to the new (or just leaves them where they are, if both versions use the same cache).

### Wait a second… what if my files changed?

`cache.adderall(`⚡`)`'s lazy approach is great for files that never change (e.g. `style.v38.css`, or`/js/2.6.0/annyang.min.js`). But if some of your files may change between versions, while their URL stays the same (e.g. `index.html`, `app-settings.json`), you can ask `cache.adderall(`⚡`)` to skip its lazy behavior for those files.

Any file that needs to be fetched from the network every time you update your service worker can be passed in a second array of URLs as `cache.adderall(`⚡`)`'s third argument.

    // In your service worker
    importScripts('js/cache.adderall.js');

    var STATIC_FILES = [
      'video/cache.adderall.demo.mp4',
      '/bootstrap/3.3.7/css/bootstrap.min.css',
      '/js/2.6.0/annyang.min.js'
    ];

    var MUTABLE_FILES = [
      'app-settings.json',
      'index.html'
    ];

    self.addEventListener('install', event => {
      event.waitUntil(
        caches.open('cache-v2').then(cache =>
          adderall.addAll(cache, STATIC_FILES, MUTABLE_FILES)
        )
      );
    });

Any URLs passed in the 3rd argument, are handled directly by the native `cache.addAll()`.

In fact, the following two commands do exactly the same thing:

    cache.addAll(['/index.html', '/main.css']);
    adderall.addAll(cache, undefined, ['/index.html', '/main.css']);

Remember: `adderall.addAll(cache, immutableURLs, mutableURLs);`

### What about HTTP caching?

If your server is configured to serve each different file with the correct caching headers, serving mutable content with a `Cache-Control: no-cache` header, and immutable content with `Cache-Control: max-age=31536000`, then you might not need `cache.adderall(`⚡`)` at all. In fact, this is the prefered approach. You can read more details on caching header best practices in Jake Archibald's excellent post.

If however you are in an environment where you can't control the caching headers of individual files, can't access the server, are not speaking with Dev Ops over a relatively minor accident involving yogurt, or you are just using GitHub Pages - give `cache.adderall(`⚡`)` a try.

Thanks Jake Archibald and Jeffrey Posnick for helping sort this out.

`cache.adderall(`⚡`)` is a free, open source, community effort.

Please help spread the word:

Tweet