Mais conteúdo relacionado Semelhante a Progressive Web Apps. What, why and how (20) Progressive Web Apps. What, why and how3. We already Did it!
Believe it or not
Responsive, mobile first layout Cache, Localstorage, etc.
8. HTML5 is a new Notness
"The biggest mistake we made as a
company was be!ng too much on HTML5
as opposed to na"ve.”
This guy
From Facebook
11. x Distribu=on problems
x Upda=ng is a pain
x Extra care with low memory phone
x Applica=on size
Native
disadvantages
21. Our Project✓ Single page app for local meetup videos
✓ Offline support via browser caches
✓ Modern, ES6 JavaScript syntax, no framework
✓ Mul"pla$orm, Android and iOS
✓ Na"ve app look & feel
✓ Fullscreen app
✓ Splash screen
✓ Home screen icon
Engineers.id
22. Our Plan✓ Design App Shell
✓ Ge!ng The Data from API
✓ Using Service Worker:
✓ Caching App Shell
✓ Caching Data
Engineers.id
✓ Na"ve-like apps:
✓ Standalone app
✓ Adding App Icons
✓ Adding Splas Screen
✓ Deploy and securing our
app
23. Tools
Chrome DevTools - Device Mode
✓Simulate device web experiences
✓Responsive breakpoint visualiza"on
✓First meaningful paint, metrics, etc
✓Service worker, manifest, etc
28. <!DOCTYPE html>
<html>
<head>
<meta charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie-edge">
<meta name="description" content="Best video resources for learn programming">
<link rel="stylesheet" href=“styles/main.css" type="text/css" media="screen"
charset="utf-8">
<link rel="stylesheet" href="styles/spinner.css" type="text/css" media="screen"
charset="utf-8">
<title>Engieers.id
</title>
</head>
31. Get The Data
Step 2
// scripts/app.js
const url = 'https:
//engineers-id-backend-
ybbwzovhnl.now.sh/api/videos'
fetch(url)
.then(response
=> response.json())
.then(json
=> {
appendData(json)
})
33. fetch Polyfill
<!-- index.html
-->
<html>
<head>
...
</head>
<body>
<!--
...
-->
<script src="scripts/vendors/fetch.js">
</script>
<script src="scripts/app.js">
</script>
</body>
</html>
35. Zoom it out!
Naviga"on begins
(17ms)
First conten$ul paint
(600ms)
First meaningful paint
(1.58s)
Time to interac"ve
(1.8s)
37. Register Service Worker
Step 3
// scripts/app.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./service-
worker.js').then(function () {
console.log('Service Worker Registered')
})
}
40. Cache The App Shell
Step 4
// service-worker.js
var cacheName = ‘engineers-id’
var filesToCache = [
'/',
'/index.html',
'/scripts/app.js',
‘/styles/main.css',
'/styles/spinner.css',
‘/images/logo.svg',
//
...
]
self.addEventListener('install', function (e) {
e.waitUntil(
caches.open(cacheName).then(function (cache) {
return cache.addAll(filesToCache)
})
)
})
42. Wait, How Service Worker actually work?!
Service worker
Installing Ac"vated
Error
Idle Push
Fetch
Terminated
Web page
Caching
App Shell
44. Caching Strategy - Cache Only
//service-worker.js
self.addEventListener('fetch', function (event) {
// If a match isn't found in the cache, the response
// will look like a connection error
event.respondWith(caches.match(event.request))
})
45. Caching Strategy - Network Only
self.addEventListener('fetch', function (event) {
event.respondWith(fetch(event.request))
// or simply don't call event.respondWith, which
// will result in default browser behaviour
})
46. Caching Strategy - Cache, failing back to network
//service-worker.js
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).then(function (response) {
return response
|| fetch(event.request)
})
)
})
47. Caching Strategy - Cache, NetworK Race
// service-worker.js
function promiseAny (promises) {
return new Promise((resolve, reject)
=> {
promises = promises.map(p
=> Promise.resolve(p))
promises.forEach(p
=> p.then(resolve))
promises
.reduce((a, b)
=> a.catch(()
=> b))
.catch(()
=> reject(Error('All failed')))
})
}
self.addEventListener('fetch', function (event) {
event.respondWith(
promiseAny([caches.match(event.request), fetch(event.request)])
)
})
48. Caching Strategy - Cache Then Network
// service-worker.js
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
})
})
)
})
49. Caching Strategy - Network Falling Back To Cache
self.addEventListener('fetch', function (event) {
event.respondWith(
fetch(event.request).catch(function () {
return caches.match(event.request)
})
)
})
50. Cache The Content
Step 5
// service-worker.js
self.addEventListener('fetch', e
=> {
e.respondWith(
caches.open(dataCacheName).then(cache
=> {
return fetch(e.request)
.then(networkResponse
=> {
cache.put(e.request, networkResponse.clone())
return networkResponse
})
.catch(()
=> {
return caches.match(e.request)
})
})
)
})
54. App Manifest
// manifest.json
{
"name": "Engineers.id",
"short_name": "eng.id",
"lang": "en-US",
"start_url": "/index.html",
"display": "standalone",
"theme_color": "#fff",
"icons": [
{
"src": "images/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
...
],
"background_color": “#fff”,
“orientation”: “portrait”
}
55. App Manifest - Display Mode
‘fullscreen’
‘standalone’
‘minimal-ui’
‘browser’
56. App Manifest - Icons
144px by 144px
128px by 128px
192px by 192px
256px by 256px
512px by 512px
57. App Manifest - Home Screen Icons
48 dp icons for
home screen and task switcher
144px by 144px
192px by 192px
48px by 48px
96px by96px
58. App Manifest - Splash Screen Icons
128 dp icons for
splash screen
128px by 128px
256px by 256px
512px by 512px
{
"name": "Engineers.id",
"short_name": "eng.id",
"lang": "en-US",
"start_url": "/index.html",
"display": "standalone",
"theme_color": "#fff",
"icons":
[],
"background_color": “#fff”,
“orientation”: “portrait”
}
60. Install Banners
{
"name": "Engineers.id",
"short_name": "eng.id",
"lang": "en-US",
"start_url": "/index.html",
"display": "standalone",
"theme_color": "#fff",
"icons": [
...
{
"src": "images/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
],
"background_color": “#fff”,
“orientation”: “portrait”
}