Building PWAs using Workbox

Building PWAs using Workbox

32c638e7a3a466d182705fb4370cbb2e?s=128

Arnelle Balane

August 01, 2020
Tweet

Transcript

  1. Software Developer, Newlogic Arnelle Balane @arnellebalane Building PWAs using Workbox

  2. Arnelle Balane Software Developer at Newlogic Google Developers Expert for

    Web Technologies I write about Web stuff on my blog, arnellebalane.com @arnellebalane
  3. None
  4. Progressive Web Apps Websites built using Web technologies, and act

    and feel like native apps
  5. ❖ 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
  6. ❖ 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
  7. Service Workers <script> if (navigator.serviceWorker) { window.addEventListener('load', () => {

    navigator.serviceWorker.register('/sw.js'); }); } </script>
  8. Service Workers // sw.js addEventListener('install', event => { /**/ });

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

    Background Sync ❖ Background Fetch ❖ Web Application Manifest Moar APIs for our PWAs!
  10. None
  11. Workbox JavaScript libraries for adding offline support to Web applications

  12. ❖ from CDN ❖ Node module ❖ Webpack plugin Using

    Workbox
  13. Credits to Afrian Hanafi dribbble.com/shots/13125619-Makers-Workshop-Concept-II

  14. Credits to Afrian Hanafi dribbble.com/shots/13125619-Makers-Workshop-Concept-II 2 pages 2 images 1

    stylesheet 1 script
  15. Import the library // sw.js importScripts('https://storage.googleapis.com/workbox-cdn/ releases/5.1.2/workbox-sw.js');

  16. Precache site assets (deprecated) workbox.precaching.precache([ '/', '/classes', '/index.css', '/index.js', '/images/image-01.jpg',

    '/images/image-02.jpg' ]);
  17. 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'} ]);
  18. Verify cache in Chrome Devtools

  19. Y u no work?

  20. Route precached assets workbox.precaching.precache([ /* ... */ ]); workbox.precaching.addRoute();

  21. 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'} ]);
  22. Now it works offline!

  23. Precaching Adding items to the cache in advance, even before

    they are used
  24. Gradually adding items to the cache as they are requested

    Runtime caching
  25. Cache a specific URL at runtime workbox.routing.registerRoute( '/images/image-01.jpg', new workbox.strategies.NetworkFirst()

    );
  26. Verify cache in Chrome Devtools

  27. Cache a URL pattern at runtime workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.NetworkFirst()

    );
  28. 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() );
  29. Runtime caching https://developers.google.com/web/tools/workbox/reference-docs /latest/module-workbox-routing Precaching https://developers.google.com/web/tools/workbox/reference-docs /latest/module-workbox-precaching More Info

  30. Workbox provides simple implementations for common service worker caching strategies

    Caching strategies
  31. Network-First Image from web.dev

  32. Network-First workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.NetworkFirst() );

  33. Network-First workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.NetworkFirst({ networkTimeoutSeconds: 3 }) );

  34. Cache-First Image from web.dev

  35. Cache-First workbox.routing.registerRoute( /\.css$/, new workbox.strategies.CacheFirst() );

  36. Stale-While-Revalidate Image from web.dev

  37. Stale-While-Revalidate workbox.routing.registerRoute( (context) => context.url.pathname.startsWith('/blog'), new workbox.strategies.StaleWhileRevalidate() );

  38. ❖ Nothing special other than they can use Workbox Plugins

    Cache-Only Network-Only
  39. The Offline Cookbook https://developers.google.com/web/fundamentals/instant-and -offline/offline-cookbook Workbox Strategies https://developers.google.com/web/tools/workbox/reference-docs /latest/module-workbox-strategies More

    Info
  40. Additional service worker behaviours without writing more boilerplate code Workbox

    plugins
  41. ❖ ExpirationPlugin ❖ BroadcastUpdatePlugin ❖ BackgroundSyncPlugin ❖ CacheableResponsePlugin ❖ RangeRequestsPlugin

    Workbox plugins
  42. Using plugins workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.CacheFirst({ plugins: [ /* plugins

    here */ ] }) );
  43. ExpirationPlugin, expire after some time workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.CacheFirst({ cacheName:

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

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

    'image-cache', plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 1 }) ] }) );
  46. ExpirationPlugin

  47. ExpirationPlugin

  48. BroadcastUpdatePlugin workbox.routing.registerRoute( /\/blog\/.+$/, new workbox.strategies.StaleWhileRevalidate({ plugins: [ new workbox.broadcastUpdate.BroadcastUpdatePlugin() ]

    }) );
  49. BroadcastUpdatePlugin, handle in main page // index.js navigator.serviceWorker.onmessage = event

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

    => { if (event.data.meta === 'workbox-broadcast-update') { displayUpdateAvailableUI(); } };
  51. BroadcastUpdatePlugin

  52. Custom Plugins https://developers.google.com/web/tools/workbox/guides /using-plugins#custom_plugins Using Plugins https://developers.google.com/web/tools/workbox/guides /using-plugins More Info

  53. Use Workbox with popular JavaScript frameworks. Webpack plugin

  54. Install dependencies npm install -D workbox-webpack-plugin

  55. GenerateSW plugin const {GenerateSW} = require('workbox-webpack-plugin'); module.exports = { /*

    ... */ plugins: [ new GenerateSW({ swDest: 'sw.js' }) ] };
  56. InjectManifest plugin const {InjectManifest} = require('workbox-webpack-plugin'); module.exports = { /*

    ... */ plugins: [ new InjectManifest({ swSrc: './www/sw.js' }) ] };
  57. 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'} ]);
  58. InjectManifest plugin, add injection point // sw.js importScripts('https://storage.googleapis.com/...'); workbox.precaching.precacheAndRoute( self.__WB_MANIFEST

    );
  59. InjectManifest plugin, build result // dist/sw.js importScripts('https://storage.googleapis.com/...'); workbox.precaching.precacheAndRoute([ {'revision':'b91028...','url':'index.329fc4.js'}, {'revision':'20420e...','url':'index.html'}

    ]);
  60. Update service worker imports // sw.js import {precacheAndRoute} from 'workbox-precaching';

    precacheAndRoute(self.__WB_MANIFEST);
  61. 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()] }) );
  62. Webpack plugin reference https://developers.google.com/web/tools/workbox/reference-doc s/latest/module-workbox-webpack-plugin Using bundlers with Workbox https://developers.google.com/web/tools/workbox/guides

    /using-bundlers More Info
  63. a.k.a I didn’t know where to put these content so

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

    workbox.strategies.StaleWhileRevalidate({ cacheName: 'google-fonts-stylesheets' }) );
  65. 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 }) ] }) );
  66. Generic fallbacks

  67. Generic fallbacks

  68. Generic fallbacks, precache fallback image workbox.precaching.precache([ {url: '/images/fallback-image.png', revision: 'v1'},

    ]);
  69. 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() );
  70. Generic fallbacks workbox.routing.setCatchHandler(async context => { if (context.request.destination === 'image')

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

    if (context.request.destination === 'image') { return workbox.precaching.matchPrecache( '/images/fallback-image.png' ); } });
  72. Generic fallbacks

  73. Generic fallbacks, for other pages

  74. Workbox https://developers.google.com/web/tools/workbox Common Recipes https://developers.google.com/web/tools/workbox/guides /common-recipes More Info

  75. ❖ Workbox caching strategies ❖ Workbox plugins ❖ Using Workbox

    with Webpack ❖ Common Workbox recipes Recap!
  76. ❖ Web Application Manifest ❖ Push Notifications ❖ Background Sync

    ❖ Web Capabilities What’s next?
  77. Building PWAs using Workbox Arnelle Balane That’s all for today!

    Thank you!