Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Progressive Web Apps, au-delà du buzzword

Progressive Web Apps, au-delà du buzzword

Le concept de Progressive Web App a pour ambition de permettre aux applications web de rivaliser, dans une certaine mesure, avec les applications natives. En s’appuyant sur quelques bonnes pratiques et certaines technologies, l'expérience utilisateur est considérablement améliorée en corrigeant par exemple les soucis de connectivité sur mobile ou en permettant l'utilisation de notifications.

Antoine Le Taxin

April 26, 2017
Tweet

More Decks by Antoine Le Taxin

Other Decks in Technology

Transcript

  1. 1. Qu’est-ce que c’est ? 2. Les usages 3. Les

    prérequis 4. Les caractéristiques
  2. 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
  3. 1. Qu’est-ce que c’est ? 2. Les usages 3. Les

    prérequis 4. Les caractéristiques
  4. • 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
  5. 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 ?
  6. 1. Qu’est-ce que c’est ? 2. Les usages 3. Les

    prérequis 4. Les caractéristiques
  7. 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
  8. 1. Qu’est-ce que c’est ? 2. Les usages 3. Les

    prérequis 4. Les caractéristiques
  9. 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
  10. 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)) ); });
  11. 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()) ); });
  12. 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/
  13. • Les moteurs de recherche reconnaissent certaines caractéristiques des PWA

    (manifest, Service Worker) • SEO classique • Ajout dans les stores (Microsoft, ...) Retrouver une PWA
  14. • Chaque page doit être accessible directement via un lien...

    • … que l’on peut partager facilement Tout partager grâce à… l’hypertexte
  15. 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" }, … ] }
  16. 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
  17. 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); }); }
  18. 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; }); }
  19. Un exemple de souscription { "endpoint": "https://random-push-service.com/some-kind-of-unique-id-1234/v2/", "keys": { "p256dh":

    "dreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7", "auth": "tBHItJI5svbpez7KI4CCXg==" } }
  20. 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');
  21. 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)); });
  22. 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')); });