Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
PWA, Au delà du buzzword
Search
Paul-Guillaume Déjardin
May 15, 2017
Programming
92
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PWA, Au delà du buzzword
Présentation PWA à la Branche Numérique de La Poste
Paul-Guillaume Déjardin
May 15, 2017
Other Decks in Programming
See All in Programming
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
290
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
420
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
500
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
110
sbt 2.0: takeoff
eed3si9n
0
160
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
190
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.7k
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
28
32k
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
160
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
0
170
phperだってパンチカードでコーディングしたい
o0h
PRO
0
340
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
370
Featured
See All Featured
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
940
RailsConf 2023
tenderlove
30
1.6k
Code Reviewing Like a Champion
maltzj
529
40k
It's Worth the Effort
3n
188
29k
Ethics towards AI in product and experience design
skipperchong
2
430
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
The Curse of the Amulet
leimatthew05
3
16k
Mobile First: as difficult as doing things right
swwweet
225
10k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Are puppies a ranking factor?
jonoalderson
2
4.1k
Transcript
PWA, au-delà du buzzword
Antoine Le Taxin Développeur / Craftsman @ModuloM Paul-Guillaume Déjardin Développeur
/ Craftsman @pgdejardin
Un cas (pas) pratique
None
None
None
1. Qu’est-ce que c’est ? 2. Les usages 3. Les
prérequis 4. Les caractéristiques
Progressive Web App, un terme marketing • PWA : web
application moderne toutes options • Spec W3C (Google, Mozilla, etc.) • Pas si nouveau que ça, on entend parler de PWA depuis 2015
1. Qu’est-ce que c’est ? 2. Les usages 3. Les
prérequis 4. Les caractéristiques
• 25% des applications sont abandonnées après la première utilisation
• 42% du temps est passé sur l’app la plus utilisée • 65% des utilisateurs n’installent aucune app chaque mois Il existe une application pour tout
Pour installer une PWA...
Les standards du web évoluent • Le web peut faire
mieux que ce que vous pensez ! https://whatwebcando.today • Pourquoi faire une application si le web peut le faire ?
1. Qu’est-ce que c’est ? 2. Les usages 3. Les
prérequis 4. Les caractéristiques
Progressive
None
Responsive
None
Safe
HTTPS only Le service worker intercepte TOUS les appels émis
depuis le client…
Plus aucune excuse • Certificats classiques • Let’s Encrypt •
https://certbot.eff.org/ (exemple sous Debian) $ wget https://dl.eff.org/certbot-auto $ chmod a+x certbot-auto $ ./path/to/certbot-auto certonly --standalone -d example.com -d www.example.com $ ./path/to/certbot-auto renew --no-self-upgrade
1. Qu’est-ce que c’est ? 2. Les usages 3. Les
prérequis 4. Les caractéristiques
Connectivity independent
Le service worker C’est un proxy réseau programmable en Javascript
avec du cache
Le SW s’installe entre le navigateur et le réseau
if ('serviceWorker' in navigator) { // Register service worker navigator.serviceWorker.register('/sw.js').then((registration)
=> { // :-) }).catch((err) => { // :-( }); } Enregistrement (app.js)
Une forme de vie extérieure • S’exécute sur un thread
différent que le code Javascript principal => pas d’accès à window, document, le DOM • Peut être réveillé même quand le navigateur n’est pas actif • Toutes les requêtes sont asynchrones • Pas de contrôle du développeur sur son cycle de vie
None
'install' 'activate' 'fetch' 'push' // notification ... Quelques events de
l’API SW
Installation (sw.js) const CACHE = `MiXit-cache::${Date.now()}`; const assets = [
'/styles/app.css', '/script/app.js, /* (...) */ ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE) .then((cache) => cache.addAll(assets)) ); });
Activation (sw.js) self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keylist) => Promise.all(
keylist .filter((key) => key !== CACHE) .map((key) => caches.delete(key)) )) .then(() => self.clients.claim()) ); });
Différentes stratégies possibles
Exemple : network fallback
Appel (sw.js) self.addEventListener('fetch', (event) =>{ event.respondWith( caches.match(event.request) .then((response) => {
return response || fetch(event.request); }) ); }); https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/
Bien calibrer son cache...
Compatibilité
Fresh
Temps moyen de validation des app mobiles
Discoverable & Linkable
• Les moteurs de recherche reconnaissent certaines caractéristiques des PWA
(manifest, Service Worker) • SEO classique • Ajout dans les stores (Microsoft, ...) Retrouver une PWA
• Chaque page doit être accessible directement via un lien...
• … que l’on peut partager facilement Tout partager grâce à… l’hypertexte
Installable & App-like
Installable Popup d'ajout sur homescreen On peut renommer l'application Elle
apparaît comme une app native
Manifest { "name": "developer.laposte.fr", "short_name": "dev.laposte", "theme_color": "#ffc928", "background_color": "#eeeeee",
"display": "standalone", "orientation": "portrait", "splash_pages": null, ... ... "icons": [ { "src": "icon-72x72.png", "sizes": "72x72", "type": "image/png" }, … ] }
App-like Ecran de chargement d'une app Page d'accueil de developer.laposte.fr
Une autre page de developer.laposte.fr
Re-engageable
Notifications • Une API comprise dans le Service Worker (Push
API) • Firebase Cloud Messaging • Un système d'autorisation via le browser • Activations / Désactivation par l'UX
Comment ça marche côté client ?
Un peu de code function getNotificationPermissionState() { if (navigator.permissions) {
return navigator.permissions.query({ name: 'notifications' }) .then(permission => { return permission.state; }); } return new Promise(resolve => { resolve(Notification.permission); }); }
Souscrire un utilisateur function subscribeUserToPush() { return getSWRegistration() .then(registration =>
{ const subscribeOptions = { applicationServerKey: urlBase64ToUint8Array('MyApplicationKey') }; return registration.pushManager.subscribe(subscribeOptions); }) .then(pushSubscription => { console.log('Received PushSubscription: ', JSON.stringify(pushSubscription)); return pushSubscription; }); }
Un exemple de souscription { "endpoint": "https://random-push-service.com/some-kind-of-unique-id-1234/v2/", "keys": { "p256dh":
"dreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7", "auth": "tBHItJI5svbpez7KI4CCXg==" } }
Et ensuite ?
Envoyer une notification const webpush = require('web-push'); // This is
the same output of calling JSON.stringify on a PushSubscription const pushSubscription = { endpoint: '.....', keys: { auth: '.....', p256dh: '.....' } }; webpush.sendNotification(pushSubscription, 'Your Push Payload Text');
...Pour finir
Recevoir une notification self.addEventListener('push', event => { logger.log('[Service Worker] Push
Received.'); const data = event.data.json(); const title = data.title; const options = { body: data.body, icon: 'images/icon.png', badge: 'images/badge.png', }; event.waitUntil(self.registration.showNotification(title, options)); });
Notifications
Interagir avec une notification self.addEventListener('notificationclick', event => { logger.log('[Service Worker]
Notification click Received.'); event.notification.close(); event.waitUntil(clients.openWindow('https://developer.laposte.fr')); });
Conclusion
Tooling • sw-toolbox • sw-precache • serviceworker-webpack-plugin • offline-plugin •
Lighthouse
None
None
Merci ! Des questions ?