Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building PWAs using Workbox

Building PWAs using Workbox

Arnelle Balane

August 01, 2020

Transcript

77 slides
  1. Arnelle Balane Software Developer at Newlogic Google Developers Expert for

    Web Technologies I write about Web stuff on my blog, arnellebalane.com @arnellebalane
  2. ❖ Can be installed to the home screen ❖ Works

    well even in intermittent or unreliable network conditions ❖ Works on any device ❖ Send notifications even when app is closed Progressive Web Apps
  3. ❖ Usually built using the application shell model, minimizing page

    refresh ❖ Generally easier to deploy and maintain than native apps ❖ SEO, URLs, etc. Progressive Web Apps
  4. Service Workers // sw.js addEventListener('install', event => { /**/ });

    addEventListener('activate', event => { /**/ }); addEventListener('fetch', event => { /**/ });
  5. ❖ Service Workers ❖ Cache API ❖ Push Notifications ❖

    Background Sync ❖ Background Fetch ❖ Web Application Manifest Moar APIs for our PWAs!
  6. Precache site assets, with versioning workbox.precaching.precache([ {url: '/', revision: 'v1'},

    {url: '/classes', revision: 'v1'}, {url: '/index.css', revision: 'v1'}, {url: '/index.js', revision: 'v1'}, {url: '/images/image-01.jpg', revision: 'v1'}, {url: '/images/image-02.jpg', revision: 'v1'} ]);
  7. Precache and route site assets workbox.precaching.precacheAndRoute([ {url: '/', revision: 'v1'},

    {url: '/classes', revision: 'v1'}, {url: '/index.css', revision: 'v1'}, {url: '/index.js', revision: 'v1'}, {url: '/images/image-01.jpg', revision: 'v1'}, {url: '/images/image-02.jpg', revision: 'v1'} ]);
  8. Runtime caching using a “match callback” workbox.routing.registerRoute( (context) => context.url.origin

    === 'https://arnelle.me', new workbox.strategies.NetworkFirst() ); workbox.routing.registerRoute( (context) => context.request.destination === 'image', new workbox.strategies.NetworkFirst() );
  9. ExpirationPlugin, expire after some time workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.CacheFirst({ cacheName:

    'image-cache', plugins: [ new workbox.expiration.ExpirationPlugin({ maxAgeSeconds: 10 }) ] }) );
  10. ExpirationPlugin, limit number of entries workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.CacheFirst({ cacheName:

    'image-cache', plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 1 }) ] }) );
  11. BroadcastUpdatePlugin, handle in main page // index.js navigator.serviceWorker.onmessage = event

    => { if (event.data.meta === 'workbox-broadcast-update') { displayUpdateAvailableUI(); } };
  12. BroadcastUpdatePlugin, handle in main page // index.js navigator.serviceWorker.onmessage = event

    => { if (event.data.meta === 'workbox-broadcast-update') { displayUpdateAvailableUI(); } };
  13. InjectManifest plugin const {InjectManifest} = require('workbox-webpack-plugin'); module.exports = { /*

    ... */ plugins: [ new InjectManifest({ swSrc: './www/sw.js' }) ] };
  14. InjectManifest plugin // sw.js importScripts('https://storage.googleapis.com/...'); workbox.precaching.precacheAndRoute([ {url: '/', revision: 'v1'},

    {url: '/classes', revision: 'v1'}, {url: '/index.css', revision: 'v1'}, {url: '/index.js', revision: 'v1'} ]);
  15. Update service worker imports import {registerRoute} from 'workbox-routing'; import {StaleWhileRevalidate}

    from 'workbox-strategies'; import {BroadcastUpdatePlugin} from 'workbox-broadcast-update'; registerRoute( /\/blog\/.+$/, new StaleWhileRevalidate({ plugins: [new BroadcastUpdatePlugin()] }) );
  16. a.k.a I didn’t know where to put these content so

    I’ll just put them at the end... Common recipes
  17. Cache Google Fonts workbox.routing.registerRoute( (context) => context.url.origin === 'https://fonts.googleapis.com', new

    workbox.strategies.StaleWhileRevalidate({ cacheName: 'google-fonts-stylesheets' }) );
  18. Cache Google Fonts workbox.routing.registerRoute( (context) => context.url.origin === 'https://fonts.gstatic.com', new

    workbox.strategies.CacheFirst({ cacheName: 'google-fonts-webfonts', plugins: [ new workbox.expiration.ExpirationPlugin({ maxAgeSeconds: 60 * 60 * 24 * 365, // one year maxEntries: 30 }) ] }) );
  19. Generic fallbacks, route all images workbox.precaching.precache([ {url: '/images/fallback-image.png', revision: 'v1'},

    ]); workbox.routing.registerRoute( (context) => context.request.destination === 'image', new workbox.strategies.NetworkOnly() );
  20. Generic fallbacks workbox.routing.setCatchHandler(async context => { if (context.request.destination === 'image')

    { return workbox.precaching.matchPrecache( '/images/fallback-image.png' ); } });
  21. Generic fallbacks, respond with fallback image workbox.routing.setCatchHandler(async context => {

    if (context.request.destination === 'image') { return workbox.precaching.matchPrecache( '/images/fallback-image.png' ); } });
  22. ❖ Workbox caching strategies ❖ Workbox plugins ❖ Using Workbox

    with Webpack ❖ Common Workbox recipes Recap!

More Decks by Arnelle Balane

Other Decks in Programming