Cristian Elias
Cristian Elias

Reputation: 115

How to tell Service Worker which files to cache

What I’m doing

I’m building a Service Worker component. I want it to have:

What I’ve tried

See it for yourself

Registration of the worker in the main thread

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/worker.js').then(function(reg) {
        navigator.serviceWorker.controller.postMessage({
            'hello': 'world',
            cacheName: 'v1',
            urlsToCache: [
                "/index.html"
            ]
        });
    }, function(err) {
        console.log('ಠ_ಠ   Nope.', err);
    });
}

The worker file

'use strict';

var cacheName,
    urlsToCache;

importScripts('/node_modules/serviceworker-cache-polyfill/index.js');

self.addEventListener('message', function (evt) {
    cacheName = evt.data.cacheName;
    urlsToCache = evt.data.urlsToCache;
});

self.addEventListener('install', function(event) {
    setTimeout(function(){
        event.waitUntil(
            caches.open(cacheName)
            .then(function(cache) {
                console.log('Opened cache:', cache);
                return cache.addAll(urlsToCache);
            })
        );
    }, 2000);

});

What is wrong with this?

I had to delay the opening of the cache by using a setTimeout, which is wrong, ugly and unreliable.

What are you trying to achieve, man? ಠ_ಠ

I want to find a way to tell the worker to wait until the message containing the paths to cache arrives.

Link to my repo

Thanks in advance.

Upvotes: 2

Views: 1597

Answers (1)

Sandro Paganotti
Sandro Paganotti

Reputation: 2313

I've sent you a Pull Request: https://github.com/cristianelias/serviceworker_component/pull/1. Basically what I did is use the cache object from the page itself as follow:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/worker.js').then(function(reg) {
      caches.open('pages').then(function(pages){
         return pages.add('test.html'); 
      }).then(function(){
         console.log('cached!'); 
      });
    }, function(err) {
      console.log('ಠ_ಠ   Nope.', err);
  });
}

And instructed the SW to only perform a cache match:

'use strict';

self.addEventListener('fetch', function(event) {
    event.respondWith(
        caches.match(event.request).then(function(match){
            return match || fetch(event.request); 
        })
    );
});

It works as expected on Chrome 45, I don't know on older versions since moving the cache object to the page is quite a new thing.

Upvotes: 1

Related Questions