A PWA is a website transformed with additional features & functionality that enhance it with native behaviors.
Progressive web apps meet 3 technical requirements
The web app manifest is a simple JSON file that tells the browser how your app should behave when 'installed' on a device.
{
"name": "HackerWeb",
"short_name": "HackerWeb",
"start_url": ".",
"display": "standalone",
"background_color": "#fff",
"description": "A simply readable Hacker News app.",
"icons": [{
"src": "images/touch/homescreen48.png",
"sizes": "48x48",
"type": "image/png"
}, {
"src": "images/touch/homescreen72.png",
"sizes": "72x72",
"type": "image/png"
}, {
"src": "images/touch/homescreen96.png",
"sizes": "96x96",
"type": "image/png"
}, {
"src": "images/touch/homescreen144.png",
"sizes": "144x144",
"type": "image/png"
}, {
"src": "images/touch/homescreen168.png",
"sizes": "168x168",
"type": "image/png"
}, {
"src": "images/touch/homescreen192.png",
"sizes": "192x192",
"type": "image/png"
}]
}
A client-side proxy that gives the developer control of the cache and how to respond to resource requests.
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(
function(registration) {
// Registration was successful
console.log(
'ServiceWorker registration successful with scope: ',
registration.scope
)
},
function(err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err)
}
)
})
}
Cache only
Network only
Cache-first - Cache, falling back to network
Cache & network race
Network first - Network falling back to cache
Stale while revalidate - Cache then network
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request)
})
)
})
//Inside service worker
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.open('mysite-dynamic').then(function(cache) {
return fetch(event.request).then(function(response) {
cache.put(event.request, response.clone())
return response
})
})
)
})
//Inside app code
var networkDataReceived = false
startSpinner()
// fetch fresh data
var networkUpdate = fetch('/data.json')
.then(function(response) {
return response.json()
})
.then(function(data) {
networkDataReceived = true
updatePage(data)
})
// fetch cached data
caches
.match('/data.json')
.then(function(response) {
if (!response) throw Error('No data')
return response.json()
})
.then(function(data) {
// don't overwrite newer network data
if (!networkDataReceived) {
updatePage(data)
}
})
.catch(function() {
// we didn't get cached data,
// the network is our last hope:
return networkUpdate
})
.catch(showErrorMessage)
.then(stopSpinner)
The web is very capable of providing a reliable, robust experience. PWAs allow us to progressively enhance web apps with native behaviors.