Text
PWAs are the missing technology link to bring the best features of the web to solve the issues of native apps and closed marketplaces.
Chris Heilmann
Alibaba
(e-commerce/China)
Source : https://developers.google.com/web/showcase/2016/pdfs/alibaba.pdf
FlipKart
(e-commerce/India)
https://developers.google.com/web/showcase/2016/flipkart
Connectivity-independant
Linkable
Installable
Re-engageable
Discoverable
Fresh
App-Like
if("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(pos => {
});
} else {
}
<meta property="og:title" content="titre"/>
<meta property="og:type" content="website"/>
Les fonctionnalités présentées font parties juste d'un toolkit.
npm i -g lighthouse
lighthouse https://google.fr
<!doctype html>
<html lang="fr">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<meta content="width=device-width, initial-scale=1.0"
name="viewport" />
<title>Ma première PWA</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
</body>
</html>
Style
Display
https://manifest-validator.appspot.com
window.addEventListener(
'beforeinstallprompt', (e) => {
if (isLoggedIn()) {
e.preventDefault();
}
});
Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
.then(req => {
console.log('Success');
}).catch(error => {
console.log('Error');
});
};
self.addEventListener('fetch', event => {
event.respondWith(
fetch(event.request)
);
});
self.addEventListener('fetch', event => {
event.respondWith(
fetch(event.request)
.then(response => {
if(response.status === 404) {
...
}
return response;
})
);
});
interface Request {
method
url
headers
context
referrer
referrerPolicy
mode
credentials
redirect
integrity
cache
bodyUsed
}
self.addEventListener('fetch', event => {
/*
let options = {
status: 200,
statustext: 'OK',
headers: { ... }
};
*/
event.respondWith(
new Response('Hello World', /*opts*/)
);
});
CacheStorage.open(cacheName)
Cache.match(request, options)
Cache.matchAll(request, options)
Cache.add(request)
Cache.addAll(requests)
Cache.put(request, response)
Cache.delete(request, options)
const cacheName = 'codelab';
const filesToCache = [
'/',
'/script.js',
'/css/style.css'
];
self.addEventListener('install', e => {
e.waitUntil(
caches.open(cacheName).then(cache => {
return cache.addAll(filesToCache);
})
);
});
self.addEventListener('fetch', e => {
e.respondWith(
caches.match(e.request)
.then(response => {
return response || fetch(e.request);
})
);
});
self.addEventListener('activate', e => {
e.waitUntil(
caches.keys().then(keyList => {
return Promise.all(keyList.map(key => {
if (key !== cacheName) {
return caches.delete(key);
}
}));
})
);
});
if(!navigator.onLine) {
...
}
window.addEventListener("offline", () => {
...
}, false);
window.addEventListener("online", () => {
...
}, false);
const indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB;
// Open (or create) the database
const open = indexedDB.open("Codelab", 1);
// Create the schema
open.onupgradeneeded = function() {
let db = open.result;
let store = db.createObjectStore("Conference", {keyPath: "id"});
let index = store.createIndex("SpeakerIndex", ["speaker"]);
};
open.onsuccess = function() {
// Start a new transaction
let db = open.result;
let tx = db.transaction("Conference", "readwrite");
let store = tx.objectStore("Conference");
let index = store.index("SpeakerIndex");
// Add some data
store.put({id: 12345, speaker: "Manu", "title": "PWA");
store.put({id: 67890, speaker: "Gauthier", "title": "VueJS");
// Query the data
let getPWA = store.get(12345);
let getVueJS = index.get(["Gauthier"]);
getPWA.onsuccess = function() {
console.log(getPWA.result);
};
getVueJS.onsuccess = function() {
console.log(getBob.result);
};
// Close the db when the transaction is done
tx.oncomplete = function() {
db.close();
};
}
localforage.setItem('somekey', {}).then(value => {
console.log(value);
})
localforage.getItem('somekey').then(value => {
console.log(value);
});
localforage.removeItem('somekey').then(() => {
console.log('Key is cleared!');
});
self.addEventListener('sync', event => {
if (event.tag == 'SYNC_SETTINGS') {
event.waitUntil(updateSettings());
}
});
navigator.serviceWorker.getRegistration()
.then(registration => {
registration.sync.register(
'SYNC_SETTINGS').then(() => {
console.log('Sync registered');
});
})
const fs = require('fs')
const javascript = fs.readFileSync('./app/assets/script.js');
app.get('/', (req, res) => {
res.push('/script.js', {
response: {'content-type': 'application/javascript'}})
.end(javascript)
res.sendFile(__dirname + '/app/index.html');
})
const options = {
key: fs.readFileSync('./server.key'),
cert: fs.readFileSync('./server.crt')
};
require('spdy').createServer(options, app).listen(3002);