Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Building PWAs using Workbox
Search
Arnelle Balane
August 01, 2020
Programming
0
220
Building PWAs using Workbox
Arnelle Balane
August 01, 2020
Tweet
Share
More Decks by Arnelle Balane
See All by Arnelle Balane
Introduction to building Chrome Extensions
arnellebalane
0
120
Color Palettes Of The Most Colorful Birds
arnellebalane
0
120
Let's build a video streaming app using Web technologies
arnellebalane
0
150
Let's build a video calling app with Web technologies and Firebase!
arnellebalane
0
140
Ridiculous Scientific Names
arnellebalane
0
240
Fishes With Terrestrial-Animal Names
arnellebalane
0
150
Making the Web more capable with Project Fugu
arnellebalane
0
120
Frontend Web Development in 2021+
arnellebalane
0
170
Extending CSS using Houdini
arnellebalane
0
110
Other Decks in Programming
See All in Programming
AIエージェント時代における TypeScriptスキーマ駆動開発の新たな役割
bicstone
4
1.5k
Goで実践するドメイン駆動開発 AIと歩み始めた新規プロダクト開発の現在地
imkaoru
4
660
iOS 17で追加されたSubscriptionStoreView を利用して5分でサブスク実装チャレンジ
natmark
0
610
(Extension DC 2025) Actor境界を越える技術
teamhimeh
1
230
Web技術を最大限活用してRAW画像を現像する / Developing RAW Images on the Web
ssssota
2
1.2k
プログラマのための作曲入門
cheebow
0
540
CSC305 Lecture 01
javiergs
PRO
1
400
フロントエンド開発に役立つクライアントプログラム共通のノウハウ / Universal client-side programming best practices for frontend development
nrslib
7
3.9k
WebエンジニアがSwiftをブラウザで動かすプレイグラウンドを作ってみた
ohmori_yusuke
0
170
Model Pollution
hschwentner
1
180
Conquering Massive Traffic Spikes in Ruby Applications with Pitchfork
riseshia
0
150
プログラミングどうやる? ~テスト駆動開発から学ぶ達人の型~
a_okui
0
190
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
Site-Speed That Sticks
csswizardry
11
880
Context Engineering - Making Every Token Count
addyosmani
5
190
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.6k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Building an army of robots
kneath
306
46k
Thoughts on Productivity
jonyablonski
70
4.9k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.2k
Mobile First: as difficult as doing things right
swwweet
224
10k
Transcript
Software Developer, Newlogic Arnelle Balane @arnellebalane Building PWAs using Workbox
Arnelle Balane Software Developer at Newlogic Google Developers Expert for
Web Technologies I write about Web stuff on my blog, arnellebalane.com @arnellebalane
None
Progressive Web Apps Websites built using Web technologies, and act
and feel like native apps
❖ 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
❖ 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
Service Workers <script> if (navigator.serviceWorker) { window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js'); }); } </script>
Service Workers // sw.js addEventListener('install', event => { /**/ });
addEventListener('activate', event => { /**/ }); addEventListener('fetch', event => { /**/ });
❖ Service Workers ❖ Cache API ❖ Push Notifications ❖
Background Sync ❖ Background Fetch ❖ Web Application Manifest Moar APIs for our PWAs!
None
Workbox JavaScript libraries for adding offline support to Web applications
❖ from CDN ❖ Node module ❖ Webpack plugin Using
Workbox
Credits to Afrian Hanafi dribbble.com/shots/13125619-Makers-Workshop-Concept-II
Credits to Afrian Hanafi dribbble.com/shots/13125619-Makers-Workshop-Concept-II 2 pages 2 images 1
stylesheet 1 script
Import the library // sw.js importScripts('https://storage.googleapis.com/workbox-cdn/ releases/5.1.2/workbox-sw.js');
Precache site assets (deprecated) workbox.precaching.precache([ '/', '/classes', '/index.css', '/index.js', '/images/image-01.jpg',
'/images/image-02.jpg' ]);
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'} ]);
Verify cache in Chrome Devtools
Y u no work?
Route precached assets workbox.precaching.precache([ /* ... */ ]); workbox.precaching.addRoute();
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'} ]);
Now it works offline!
Precaching Adding items to the cache in advance, even before
they are used
Gradually adding items to the cache as they are requested
Runtime caching
Cache a specific URL at runtime workbox.routing.registerRoute( '/images/image-01.jpg', new workbox.strategies.NetworkFirst()
);
Verify cache in Chrome Devtools
Cache a URL pattern at runtime workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.NetworkFirst()
);
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() );
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
Workbox provides simple implementations for common service worker caching strategies
Caching strategies
Network-First Image from web.dev
Network-First workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.NetworkFirst() );
Network-First workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.NetworkFirst({ networkTimeoutSeconds: 3 }) );
Cache-First Image from web.dev
Cache-First workbox.routing.registerRoute( /\.css$/, new workbox.strategies.CacheFirst() );
Stale-While-Revalidate Image from web.dev
Stale-While-Revalidate workbox.routing.registerRoute( (context) => context.url.pathname.startsWith('/blog'), new workbox.strategies.StaleWhileRevalidate() );
❖ Nothing special other than they can use Workbox Plugins
Cache-Only Network-Only
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
Additional service worker behaviours without writing more boilerplate code Workbox
plugins
❖ ExpirationPlugin ❖ BroadcastUpdatePlugin ❖ BackgroundSyncPlugin ❖ CacheableResponsePlugin ❖ RangeRequestsPlugin
Workbox plugins
Using plugins workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.CacheFirst({ plugins: [ /* plugins
here */ ] }) );
ExpirationPlugin, expire after some time workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.CacheFirst({ cacheName:
'image-cache', plugins: [ new workbox.expiration.ExpirationPlugin({ maxAgeSeconds: 10 }) ] }) );
ExpirationPlugin, custom cache name workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.CacheFirst({ cacheName: 'image-cache',
plugins: [ new workbox.expiration.ExpirationPlugin({ maxAgeSeconds: 10 }) ] }) );
ExpirationPlugin, limit number of entries workbox.routing.registerRoute( /\.jpg$/, new workbox.strategies.CacheFirst({ cacheName:
'image-cache', plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 1 }) ] }) );
ExpirationPlugin
ExpirationPlugin
BroadcastUpdatePlugin workbox.routing.registerRoute( /\/blog\/.+$/, new workbox.strategies.StaleWhileRevalidate({ plugins: [ new workbox.broadcastUpdate.BroadcastUpdatePlugin() ]
}) );
BroadcastUpdatePlugin, handle in main page // index.js navigator.serviceWorker.onmessage = event
=> { if (event.data.meta === 'workbox-broadcast-update') { displayUpdateAvailableUI(); } };
BroadcastUpdatePlugin, handle in main page // index.js navigator.serviceWorker.onmessage = event
=> { if (event.data.meta === 'workbox-broadcast-update') { displayUpdateAvailableUI(); } };
BroadcastUpdatePlugin
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
Use Workbox with popular JavaScript frameworks. Webpack plugin
Install dependencies npm install -D workbox-webpack-plugin
GenerateSW plugin const {GenerateSW} = require('workbox-webpack-plugin'); module.exports = { /*
... */ plugins: [ new GenerateSW({ swDest: 'sw.js' }) ] };
InjectManifest plugin const {InjectManifest} = require('workbox-webpack-plugin'); module.exports = { /*
... */ plugins: [ new InjectManifest({ swSrc: './www/sw.js' }) ] };
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'} ]);
InjectManifest plugin, add injection point // sw.js importScripts('https://storage.googleapis.com/...'); workbox.precaching.precacheAndRoute( self.__WB_MANIFEST
);
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'}
]);
Update service worker imports // sw.js import {precacheAndRoute} from 'workbox-precaching';
precacheAndRoute(self.__WB_MANIFEST);
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()] }) );
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
a.k.a I didn’t know where to put these content so
I’ll just put them at the end... Common recipes
Cache Google Fonts workbox.routing.registerRoute( (context) => context.url.origin === 'https://fonts.googleapis.com', new
workbox.strategies.StaleWhileRevalidate({ cacheName: 'google-fonts-stylesheets' }) );
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 }) ] }) );
Generic fallbacks
Generic fallbacks
Generic fallbacks, precache fallback image workbox.precaching.precache([ {url: '/images/fallback-image.png', revision: 'v1'},
]);
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() );
Generic fallbacks workbox.routing.setCatchHandler(async context => { if (context.request.destination === 'image')
{ return workbox.precaching.matchPrecache( '/images/fallback-image.png' ); } });
Generic fallbacks, respond with fallback image workbox.routing.setCatchHandler(async context => {
if (context.request.destination === 'image') { return workbox.precaching.matchPrecache( '/images/fallback-image.png' ); } });
Generic fallbacks
Generic fallbacks, for other pages
Workbox https://developers.google.com/web/tools/workbox Common Recipes https://developers.google.com/web/tools/workbox/guides /common-recipes More Info
❖ Workbox caching strategies ❖ Workbox plugins ❖ Using Workbox
with Webpack ❖ Common Workbox recipes Recap!
❖ Web Application Manifest ❖ Push Notifications ❖ Background Sync
❖ Web Capabilities What’s next?
Building PWAs using Workbox Arnelle Balane That’s all for today!
Thank you!