PWA
Crash Course


My name is Rafael Fernandes and that's my face.



AdamModus
@AdamModus
https://adammode.xyz
Sup?

Amsterdam

Lisbon


About me


That's me!

Rabobank
About me
Agenda

- PWA? WTF?
- PWA main points
- Philosophy time
- Web App Manifest
- Service Worker FTW
- Life cycle
- Gotchas
- Extras
- P is for Performance!
- Client side storage
- Q&A
PWA? WTF?

- Progressive - Works for every user, regardless of browser choice
- Responsive - Fits any form factor! 📱 / 💻 / 📺 / etc...
- Reliable - Enhanced with service workers to work on uncertain network conditions
- App-like - Feels like a native app, with an immersive user experience
- Fresh - Always up-to-date thanks to the service worker update process
- Safe - Served only via HTTPS to ensure user's privacy and communication safety
- Discoverable - Is identifiable as an "application" thanks to W3C manifest and service worker registration scope, allowing search engines to find it
- Re-engageable - Makes re-engagement easy through features like push notifications
- Installable - Allows users to add PWAs to their home screen
- Linkable - Easily shared via URL, does not require complex installation
- Fast - Respond quickly to user interactions smoothly and with no janky scrolling.
PWA? WTF?
Technology behind PWAs:
- Service Workers - It enables asset caching and background tasks
- IndexedDB - A database in the browser
- LocalStorage - A place to store small amounts of data in the browser
- Mobile sensors API - Interface hardware directly: touch, mic, camera, motions, vibration, location, etc...
- Web App Manifest - To add the PWA to the home screen and provide some more immersive experience
- Web workers - Multi-threading possibilities
Philosophy time!

Philosophy time!

The worst we can do to the user is give him nothing!

Philosophy time!

- Cached your assets, even in real time
- Cached information is better than nothing, users are happier in all scenarios: Online / Offline / Li-fi
- Think about multiple form factors
- Accessibility is very relevant
- Check your performance measures
We're here for our users so ultimately we should focus on user experience!
Offline first philosophy:
Web App Manifest


{
"short_name": "Offline survivor",
"name": "Surviving the offline status",
"description": "An example PWA",
"background-color": "#FAFAFA",
"icons": [
{
"src": "imgs/icon/favicon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "imgs/icon/favicon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "imgs/icon/favicon-196x196.png",
"sizes": "196x196",
"type": "image/png"
}
],
"start_url": "/index.html",
"display": "standalone"
}
<link rel="manifest" href="manifest.json">
Service Worker FTW

web page
server
Service Worker FTW

SW.js
web page
server
Cache storage (sw cache)

SW.js
web page
server
Cache storage (sw cache)
Service Worker FTW
Has its own thread (remember web workers?)
No DOM access!
Caching
Versioning
Allows offline functionality
Able to intercept fetch requests
Useful in slow connectivity scenarios / li-fi
Must be served via HTTPS
It's still all javascript!
Service Worker FTW

Checking availability

Service Worker FTW

Registering a service worker
Yep, it's that easy!

Service Worker FTW

Install
First event, triggered as soon as it executes
Opportunity to start caching before being able to control clients

Service Worker FTW

Activate
When old service worker is gone
New service worker is in control
Time to migrate databases / delete old caches

Service Worker FTW
Service Worker FTW

Cool diagram!

Careful with your scope!


Service Worker FTW

Skipping the waiting phase
When you really want old service worker gone

Service Worker FTW

Updating... Manually? ¯\_(⊙︿⊙)_/¯
It's also possible to force an update via code!

Service Worker FTW

You can detect when you're online and offline!

Service Worker FTW

Services workers aren't the only ones who can access cache storage

Service Worker FTW

P is for Performance!
The web is for everyone!
The biggest emerging markets do not have widespread high bandwith data (e.g. 4G)
Not everybody has an iMac 8K or a Samsung Galaxy Edge 27 Chrome Edition
We have to make sure it's snappy!
Not your average user

Your average user

VS

P is for Performance!
Useful websites for your reference:
whatdoesmysitecost.com - Know how much your website costs in a metered data connection
webpagetest.org - Test your website from all around the world plus some useful insights
Google PSI - (Page Speed Insigths) Extremely useful tool to find low hanging fruit
Google Lighthouse - Runs audits for performance, accessibility and PWAs. Can be used as a Chrome Extension or a Node module

P is for Performance!
Making your data smaller
Compress and cache
- Easily achievable by configuring web server: github.com/h5bp/server-configs
Gzip text-based assets
Brotli for higher compression ratio
Good build tools (e.g. Webpack):
- Tree shaking
- Lazy loading
- Code Splitting
- Whatever they invent next!

P is for Performance!
Look after your image(s)
Include image optimisation in build process
Progressive JPEG - Progressive rendering
WebP is a modern image format that provides superior lossless and lossy compression for images on the web
Lazy load images - Intersection observer

P is for Performance!
Look after your image(s)
// create observer
const observer = new IntersectionObserver(onChange);
function onChange(changes) {
changes.forEach(change => {
// take image url from `data-src` attribute
change.target.src = change.target.dataset.src;
// stop observing the current target
observer.unobserve(change.target);
});
}
// convert node list to array
const imgs = [ ...document.querySelectorAll('.lazy') ];
// observe each image
imgs.forEach(img => observer.observe(img));

P is for Performance!
FONTS!
Optimise web fonts - use lightweight woff2
Most browsers don't render text until the font is available
Users have to wait to read text they likely already have
body {
font-family: Arial, sans-serif;
}
body.has-fonts-loaded {
font-family: "My fancy font";
}
someFontLoader
.load('My fancy font')
.then(() => {
document.body.classList.add('has-fonts-loaded');
});
CSS
JS

P is for Performance!
FONTS!
Most browsers don't render text until the font is available
Users have to wait to read text they likely already have
@font-face {
font-family: MySuperDuperFont;
src: url(/path/to/fonts/MySuperDuperFont.woff) format('woff'),
url(/path/to/fonts/MySuperDuperFont.eot) format('eot');
font-weight: 400;
font-style: normal;
font-display: swap;
}

P is for Performance!
Golden Rule
Inline critical CSS & load the rest async
Critical CSS within first 14kb
Why that number? First round trip data
The last slide, phew!

OK, I'll shut up now.
Unless, maybe...
Questions?


PWA Crash Course - 2018
By ajrkemp
PWA Crash Course - 2018
- 1,145