Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@aleemb
Forked from ganapativs/workbox-4.3.1-notes.js
Created August 30, 2019 08:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aleemb/9d62f713e4d318c379e9b2a294695dbb to your computer and use it in GitHub Desktop.
Save aleemb/9d62f713e4d318c379e9b2a294695dbb to your computer and use it in GitHub Desktop.
Workbox - 4.3.1 - Notes
/* globals importScripts, workbox */
// https://developers.google.com/web/fundamentals/primers/service-workers/
// https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading
// https://developers.google.com/web/tools/workbox/modules/workbox-sw#using_workbox_sw_via_cdn
importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js');
if (workbox) {
console.log(`Yay! Workbox is loaded 🎉`);
} else {
console.log(`Boo! Workbox didn't load 😬`);
}
/* --------------- */
// https://developers.google.com/web/tools/workbox/guides/configure-workbox#configure_debug_builds_vs_production_builds
// Force development builds
if (process.env.NODE_ENV !== 'production') {
console.log('This is a dev-only log message!');
workbox.setConfig({ debug: true });
}
/* --------------- */
// https://developers.google.com/web/tools/workbox/modules/workbox-core#view_and_change_the_default_cache_names
workbox.core.setCacheNameDetails({
prefix: 'tracxn',
suffix: 'v1',
precache: 'install-time',
runtime: 'run-time',
googleAnalytics: 'ga',
});
/* --------------- */
// https://developers.google.com/web/tools/workbox/modules/workbox-precaching#incoming_requests_for_precached_files
workbox.precaching.precacheAndRoute(
['/styles/index.0c9a31.css', '/scripts/main.0d5770.js', { url: '/index.html', revision: '383676' }],
{
// Ignore all URL parameters.
ignoreURLParametersMatching: [/.*/],
// https://developers.google.com/web/tools/workbox/modules/workbox-precaching#directory_index
// directoryIndex: null,
// https://developers.google.com/web/tools/workbox/modules/workbox-precaching#clean_urls
cleanUrls: false,
},
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_regular_expression_route
workbox.routing.registerNavigationRoute(
// Assuming '/single-page-app.html' has been precached,
// look up its corresponding cache key.
workbox.precaching.getCacheKeyForURL('/single-page-app.html'),
// workbox.precaching.getCacheKeyForURL('/a/user/dashboard'),
{
whitelist: [new RegExp('/blog/')],
blacklist: [new RegExp('/blog/restricted/')],
},
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/modules/workbox-routing#defining_a_route_for_non-get_requests
workbox.routing.registerRoute(new RegExp('/api/.*.json'), new workbox.strategies.StaleWhileRevalidate(), 'POST');
// https://developers.google.com/web/tools/workbox/modules/workbox-strategies#changing_the_cache_used_by_a_strategy
workbox.routing.registerRoute(
new RegExp('/images/'),
new workbox.strategies.CacheFirst({
cacheName: 'image-cache',
}),
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/modules/workbox-strategies#using_plugins
workbox.routing.registerRoute(
new RegExp('/images/'),
new workbox.strategies.CacheFirst({
cacheName: 'image-cache',
plugins: [
new workbox.expiration.Plugin({
// Only cache requests for a week
maxAgeSeconds: 7 * 24 * 60 * 60,
// Only cache 10 requests.
maxEntries: 10,
}),
],
}),
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests#force_caching_of_opaque_responses
workbox.routing.registerRoute(
'https://cdn.google.com/example-script.min.js',
new workbox.strategies.CacheFirst({
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [0, 200],
}),
],
}),
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/guides/storage-quota#what_configuration_options_are_supported
workbox.routing.registerRoute(
// Match common image extensions.
new RegExp('.(?:png|gif|jpg|svg)$'),
// Use a cache-first strategy with the following config:
new workbox.strategies.CacheFirst({
// You need to provide a cache name when using expiration.
cacheName: 'images',
plugins: [
new workbox.expiration.Plugin({
// Keep at most 50 entries.
maxEntries: 50,
// Don't keep any entries for more than 30 days.
maxAgeSeconds: 30 * 24 * 60 * 60,
// Automatically cleanup if quota is exceeded.
purgeOnQuotaError: true,
}),
],
}),
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/guides/common-recipes#google_fonts
// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
workbox.routing.registerRoute(
/^https:\/\/fonts\.googleapis\.com/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'google-fonts-stylesheets',
}),
);
/* --------------- */
// Cache the underlying font files with a cache-first strategy for 1 year.
workbox.routing.registerRoute(
/^https:\/\/fonts\.gstatic\.com/,
new workbox.strategies.CacheFirst({
cacheName: 'google-fonts-webfonts',
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [0, 200],
}),
new workbox.expiration.Plugin({
maxAgeSeconds: 60 * 60 * 24 * 365,
maxEntries: 30,
}),
],
}),
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/guides/common-recipes#force_a_timeout_on_network_requests
workbox.routing.registerRoute(
'https://hacker-news.firebaseio.com/v0/api',
new workbox.strategies.NetworkFirst({
networkTimeoutSeconds: 3,
cacheName: 'stories',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 50,
maxAgeSeconds: 5 * 60, // 5 minutes
}),
],
}),
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/guides/common-recipes#cache_resources_based_on_resource_type
workbox.routing.registerRoute(
// Custom `matchCallback` function
({ event }) => event.request.destination === 'audio',
new workbox.strategies.CacheFirst({
cacheName: 'audio',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
}),
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/guides/common-recipes#access_caches_from_your_web_apps_code
// Inside app.js:
async function addToCache(urls) {
const myCache = await window.caches.open('my-cache');
await myCache.addAll(urls);
}
// Call addToCache whenever you'd like. E.g. to add to cache after a page load:
window.addEventListener('load', () => {
// ...determine the list of related URLs for the current page...
addToCache(['/static/relatedUrl1', '/static/relatedUrl2']);
});
// Inside service-worker.js:
workbox.routing.registerRoute(
new RegExp('/static/'),
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'my-cache', // Use the same cache name as before.
}),
);
/* --------------- */
// https://developers.google.com/web/tools/workbox/modules/workbox-window
// eslint-disable-next-line import/first
(async () => {
if ('serviceWorker' in navigator) {
const { Workbox } = await import('workbox-window');
const wb = new Workbox('/sw.js');
wb.addEventListener('activated', event => {
// `event.isUpdate` will be true if another version of the service
// worker was controlling the page when this version was registered.
if (!event.isUpdate) {
console.log('Service worker activated for the first time!');
// If your service worker is configured to precache assets, those
// assets should all be available now.
}
});
wb.addEventListener('waiting', event => {
console.log(
`A new service worker has installed, but it can't activate` +
`until all tabs running the current version have fully unloaded.`,
);
});
// https://developers.google.com/web/tools/workbox/modules/workbox-window#examples 👌
// https://developers.google.com/web/tools/workbox/modules/workbox-broadcast-cache-update
wb.addEventListener('message', event => {
if (event.data.type === 'CACHE_UPDATED') {
const { updatedURL } = event.data.payload;
console.log(`A newer version of ${updatedURL} is available!`);
}
});
wb.addEventListener('activated', event => {
// Get the current page URL + all resources the page loaded.
const urlsToCache = [window.location.href, ...performance.getEntriesByType('resource').map(r => r.name)];
// Send that list of URLs to your router in the service worker.
wb.messageSW({
type: 'CACHE_URLS',
payload: { urlsToCache },
});
});
wb.register();
}
})();
/* --------------- */
// https://developers.google.com/web/tools/workbox/modules/workbox-window#the_very_first_time_a_service_worker_is_installed
const wb = new Workbox('/sw.js');
wb.addEventListener('installed', event => {
if (!event.isUpdate) {
// First-installed code goes here...
}
});
wb.register();
/* --------------- */
// https://developers.google.com/web/tools/workbox/modules/workbox-window#window_to_service_worker_communication
// sw.js
const SW_VERSION = '1.0.0';
addEventListener('message', (event) => {
if (event.data.type === 'GET_VERSION') {
event.ports[0].postMessage(SW_VERSION);
}
});
// Code in main.js (running in the window):
const wb = new Workbox('/sw.js');
wb.register();
const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);
/* --------------- */
// Advanced recipes 👆
/* --------------- */
/**
More resources:
- https://developers.google.com/web/tools/workbox/guides/advanced-recipes
- https://blog.hasura.io/strategies-for-service-worker-caching-d66f3c828433/
Clear-Site-Data: cookies, cache
Kill switch 👆
- https://serviceworke.rs/
- https://serviceworke.rs/offline-fallback_service-worker_doc.html
Offline html fallback 👆
*/
/* --------------- */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment