Skip to content

Instantly share code, notes, and snippets.

@addyosmani
Last active January 20, 2024 16:14
Show Gist options
  • Star 91 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save addyosmani/0e1cfeeccad94edc2f0985a15adefe54 to your computer and use it in GitHub Desktop.
Save addyosmani/0e1cfeeccad94edc2f0985a15adefe54 to your computer and use it in GitHub Desktop.
Workbox recipes

Workbox runtime caching recipes

Your Service Worker script will need to import in Workbox and initialize it before calling any of the routes documented in this write-up, similar to the below:

importScripts('workbox-sw.prod.v1.3.0.js');
const workbox = new WorkboxSW();

// Placeholder array populated automatically by workboxBuild.injectManifest()
workbox.precache([]);

As a reminder, Workbox supports a number of different runtime caching strategies.

Cache all Google Fonts requests (up to a maximum of 30 cache entries)

Uses a cacheFirst strategy.

workbox.router.registerRoute('https://fonts.googleapis.com/(.*)',
  workbox.strategies.cacheFirst({
    cacheName: 'googleapis',
    cacheExpiration: {
      maxEntries: 30
    },
    cacheableResponse: {statuses: [0, 200]}
  })
);

cacheableResponse determines if something can be cached based on the response's status code. Above, the response will be cached if the response code is 0 or 200.

Cache all images using an extension whitelist

Uses a cacheFirst strategy.

workbox.router.registerRoute(/\.(?:png|gif|jpg|svg)$/,
  workbox.strategies.cacheFirst({
    cacheName: 'images-cache'
  })
);

Cache all scripts and stylesheets using an extension whitelist

Uses a staleWhileRevalidate strategy.

workbox.router.registerRoute(/\.(?:js|css)$/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: 'static-resources'
  })
);

Cache all requests from multiple origins

Uses a staleWhileRevalidate strategy. Here we're registering routes for anything from the googleapis.com and gstatic.com origins:

workbox.router.registerRoute(/.*(?:googleapis|gstatic)\.com.*$/, 
workbox.strategies.staleWhileRevalidate());

I often like to keep separate cache names for each of the origins I'm caching requests for. Doing this could look like:

workbox.router.registerRoute(/.*(?:googleapis)\.com.*$/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: 'googleapis-cache'
  })
);

workbox.router.registerRoute(/.*(?:gstatic)\.com.*$/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: 'gstatic-cache'
  })
);

Cache all requests from a specific origin, limited to 50 entries. Purge entries in the cache once they're older than 5 minutes.

Uses a cacheFirst strategy.

workbox.router.registerRoute(
    'https://hacker-news.firebaseio.com/v0/*',
    workbox.strategies.cacheFirst({
        cacheName: 'stories',
        cacheExpiration: {
            maxEntries: 50,
            maxAgeSeconds: 300 // 5 minutes
        },
        cacheableResponse: {statuses: [0, 200]}
    })
);

Cache all the resources from a specific subdirectory

Uses a staleWhileRevalidate strategy.

For a sub-directory /static/:

workbox.router.registerRoute(/static/(.*), workbox.strategies.staleWhileRevalidate())

As you've probably guessed, most of the path matching for setting up these routes just involves getting the regex right.

Register express style route paths (e.g /path/:foo)

workbox.router.registerRoute('/items/:itemId',
  workbox.strategies.staleWhileRevalidate({
    cacheName: 'cache-with-expiration',
    cacheExpiration: {
      maxEntries: 20,
      maxAgeSeconds: 120
    }
  })
);
@malixsys
Copy link

  workbox.router.registerRoute(/static\/(.*)/, workbox.strategies.staleWhileRevalidate())

@dannyrb
Copy link

dannyrb commented May 10, 2018

Should workbox.router be workbox.routing in workbox-sw.js 3.2?

@olso
Copy link

olso commented Apr 30, 2020

@addyosmani How would one cache images that have url params after extension, and images that don't have extension at all

e.g. https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/-122.337798,37.810550,9.67,0.00,0.00/1000x600@2x?access_token=YOUR_MAPBOX_ACCESS_TOKEN

Is it possible to runtime cache based on Content-Type? Because this doesn't work for me

{
          // urlPattern: IMG_REGEX,
          handler: "CacheFirst",
          options: {
            cacheableResponse: {
              headers: {
                "content-type": "image/*",
              },
            },
            cacheName: "images",
            expiration: {
              maxEntries: 200,
              maxAgeSeconds: ONE_MONTH_IN_SECONDS,
            },
          },
        },

I use https://regex101.com/r/YrgpUf/3 to match images that have urls params after extension e.g. .png?optimize=true

@imbdb
Copy link

imbdb commented Jul 26, 2020

@olso

Workbox provides destination of a route which you can use as below

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    cacheName: 'image-cache',
  })
);

read here for the types that request.destination can have
https://developer.mozilla.org/en-US/docs/Web/API/RequestDestination

@awais951
Copy link

Verify Github on Galxe. gid:28HrWFgTxannzE8QdzhHUN

@Lisandronunez
Copy link

Does anyone know how to include specific js files from the cache?

USE THIS CODE

registerRoute(
({request}) => request.destination === 'script' ||
request.destination === 'style',
new StaleWhileRevalidate({
cacheName: 'ag-static-resources',
})
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment