cache remote HTTP asset
Asked Answered
C

1

9

I wish to use Workbox for caching local as well as remote image assets. Is this currently supported, if so how?

Essentially I'd like to have the following functionality:

workboxBuild.injectManifest({
    swSrc: 'app/sw.js',
    swDest: 'build/sw.js',
    globDirectory: 'build',
    globPatterns: [
      '*.css',
      'index.html',
      'app.js',
      'http://remote/image.jpg'
    ],

If I manually add the remote HTTP asset to the generated service worker file, that works (see below) but I wish to generate that service worker file without having to manually edit it.

importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js');

if (workbox) {
  console.log(`Yay! Workbox is loaded 🎉`);
  workbox.precaching.precacheAndRoute([
  {
    "url": "app.css",
    "revision": "f8d6a881fb9d586ef6fd676209e1613b"
  },
  {
    "url": "index.html",
    "revision": "ce6238d5b3c1e4e559349549c9bd30aa"
  },
  {
    "url": "app.js",
    "revision": "4357dbdbcc80dcfbe1f8198ac0313009"
  },
  {
    "url": "http://remote/image.jpg"
  }
]);

} else {
  console.log(`Boo! Workbox didn't load 😬`);
}
Cate answered 23/8, 2018 at 11:6 Comment(0)
C
3

Precaching remote assets isn't supported. That's not likely to change. Workbox needs to take a "snapshot" of each resource prior to deployment, as part of a build process, in order to populate and update its cache, while serving them cache-first. While you could theoretically make an HTTP request for a remote resource as part of your build process, in order to obtain versioning information for it, there's no guarantee that that remote resource won't be re-deployed outside of the deployment cycle of your first-party assets. This could leave you in a situation in which Workbox thinks it has the latest version of http://example.com/image.jpg, and never picks up a recent update to it.

The way to handle third-party, remote assets is to use runtime routing along with a caching strategy that gives you the freshness guarantees you consider appropriate for a particular type of asset. If you want a given asset to be automatically cached as soon as your service worker is installed, you can add in your own install handler that will "prime" the runtime cache for you.

This would look something like:

// Workbox will continue to precache and keep
// the local assets it knows about up to date.
workbox.precaching.precacheAndRoute([...]);

const cacheName = 'image-cache';

// Make sure that these URLs support CORS!
// Otherwise, the cache.addAll() call will fail,
// and you'll have to explicitly call cache.put()
// for each resource.
const thirdPartyUrls = [
  'https://example.com/image.jpg',
  // Any other URLs.
];

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

workbox.routing.registerRoute(
  new RegExp('^https://example.com/'),
  // Use whichever strategy you want.
  workbox.strategies.staleWhileRevalidate({
    cacheName,
    // Use whatever plugins you want.
    plugins: [...],
  }),
);
Corticate answered 7/9, 2018 at 15:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.