The PWA Philosophy
Matt Wilber
@greenzeta
greenzeta.com
What is a PWA?
“Progressive Web Apps (PWAs) are web applications that load like regular web pages or websites but can offer the user functionality traditionally available only to native applications.”
-- The Book of Knowledge (Wikipedia)
Why Go PWA?
- Improve web experience
-
App store politics
-
Crowded marketplace
-
Difficult to differentiate
-
Review process
-
-
Leverage existing search ranking
-
Low barrier to entry
-
Use existing web technology
-
Works on all platforms
-
-
Small Footprint
PWAs are
much more
than that
The PWA Philosophy
-
Accessibility
-
Performance
-
Native features
Progressive Web Apps make an adaptive experience that fits as diverse an audience as possible.
Focusing on:
Accessibility means
bigger audience
-
People consume information in different ways.
-
Text, Images, Sound.
-
-
Accessibility is not an add-on.
-
Present your information in as many ways as possible.
-
Don't accommodate disabilities, embrace different perspectives.
-
-
Leverage established techniques:
-
Responsive design
-
Semantic HTML
-
Performance saves users & bandwidth
-
You have 4 seconds to get their attention.
-
Prioritize features.
-
Basic functionality available right away.
-
Lazy load everything else.
-
-
Cache static files.
-
Pull new content in the background.
-
-
Optimize graphics.
-
Use SVG where possible.
-
Limit web fonts.
-
Modern browsers afford native features
-
Web Manifest (Installation)
-
Service Worker
-
Fetch API
-
Cache API
-
Sync API
-
Push Notifications
-
-
LocalStorage / IndexedDB
-
Location API
-
GetUserMedia()
3 Minimum Requirements to qualify as a PWA
-
SSL
-
Service Worker
-
Web Manifest
Turn any website into a PWA
in 10 minutes
( assuming SSL )
Add Web Manifest
{
"name": "GreenZeta Progressive Web App Demo",
"short_name": "GZ PWA",
"theme_color": "#7bb951",
"background_color": "#111313",
"display": "fullscreen",
"Scope": "/",
"start_url": "/",
"icons": [
{
"src": "/assets/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"splash_pages": null
}
Add Metadata Alternative
<meta name="viewport" content="width=device-width">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="theme-color" content="#7bb951">
<meta name="mobile-web-app-capable" content="yes">
<link rel="apple-touch-icon" href="assets/icons/icon-512x512.png">
<link rel="apple-touch-icon" sizes="72x72" href="assets/icons/icon-72x72.png">
<link rel="apple-touch-icon" sizes="144x144" href="assets/icons/icon-144x144.png">
<link rel="apple-touch-icon" sizes="512x512" href="assets/icons/icon-512x512.png">
Register Service Worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
Add A Caching Strategy
self.addEventListener('install', function(event){
console.log('[SW] installing...');
event.waitUntil(caches.open('static')
.then(function(cache){
console.log('[SW] precaching');
cache.addAll([
'/',
'/index.html'
]);
}));
});
self.addEventListener('fetch', function(event){
event.respondWith(
caches.match(event.request)
.then(function(response){
if(response){
return response;
}else{
return fetch(event.request);
}
})
);
});
Install Prompt
(optional)
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
// Store the install prompt event
deferredPrompt = e;
console.log('install prompt ready');
});
document.getElementById('install').addEventListener('click', (e)=>{
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the prompt');
} else {
console.log('User dismissed the prompt');
}
deferredPrompt = null;
});
});
How to approach building a PWA
War of the Worlds Broadcast
-
2012 - Began as HTML5 audio demo
-
2018 - Rebuilt as a PWA
Rethinking the website as a PWA
-
App Shell
-
In-line svgs
-
In-line javascript
-
Minimal necessary CSS
-
-
Eliminate jQuery
-
document.QuerySelector()
-
fetch()
-
Responsive Design
-
Graphically rich layout needed to look good at any resolution.
-
Combination of scaling and re-positioning
-
Moving previous control overlay to an action button + slide-out menu
Desktop
Phone
App Shell
- index.html - 10k in size. Contains everything to display a minimally usable app.
- First meaningful paint - inline svg, action button, menu w/ description
Lazy Loading
- Don't make user wait for entire site to load.
- Audio streams while images are loading
- Provide indication that more is coming.
- Entertaining progress bar
Native Features
-
Offline Access
-
WebAudio API
-
Chromecast
-
Push Notification
Optimization
- Lighthouse, available through Chrome dev tools.
- Don't get hung up with the scores.
Source Code
github.com/mwilber/gz-10-minute-pwa
Check Out
waroftheworldsbroadcast.com
Follow @greenzeta on Twitter
Slides
slides.com/greenzeta/pwa-philosophy
greenzeta.com
Google PWA Checklist
developers.google.com/web/progressive-web-apps/checklist