Le web progressive : les premiers pas dans le développement d’une PWA

Progressive web app pwa sqli

Le web évolue en permanence à travers de nouvelles fonctionnalités toujours plus innovantes. On peut maintenant faire d’un site web une application qui utilise les dernières technologies des smartphones. Les grands acteurs du web permettent cela à travers les navigateurs intégrant de nouvelles spécifications toujours plus à la pointe. Le W3C évolue avec eux pour organiser le web et ces nouvelles techniques. En quelques années, nous sommes passés de liens hypertextes à des applications complexes, et ce n’est que le début. Je vous propose aujourd’hui de faire l’état des lieux de l’évolution du web à travers les PWA (progressive web apps) et l’amélioration progressive.  

Etat de l’art des PWA

Le terme PWA est né de l’association des deux termes « web app » (application web) et « progressive enhancement » (principe de l’amélioration progressive). Il a été inventé par Frances Berriman et Alex Russell en 2015. Vous pourrez retrouver l’article « Progressive Web Apps: Escaping Tabs Without Losing Our Soul » (en anglais) qui a marqué le début des PWA.  

Ce n’est pas une technologie comme pourrait l’être un framework ou une librairie JavaScript. C’est avant tout un terme qui met l’accent sur le principe de l’amélioration progressive. Aussi, c’est une manière de penser les applications web qui est mise en avant. Pour fournir une base de réflexion sur l’amélioration des web apps, les auteurs proposent d’implémenter de nouvelles fonctionnalités bien précises. 

Généralement, la base d’une progressive web app est qu’elle soit installable sur un ordinateur, une tablette ou un smartphone. Elle donne la possibilité d’utiliser certaines fonctionnalités d’une application native d’un smartphone grâce aux navigateurs qui permettent d’avoir un rendu similaire à celles-ci (absence de barre de navigation comme une vraie app). 

Avantages d’une PWA :  

  • Un développement unique  
  • Accès via le web 
  • Installation sur le périphérique 
  • Accessibles hors ligne 
  • Notifications push  
  • Peu coûteuses 

Inconvénient d’une PWA : 

  • Accès réduit aux technologies du périphérique mais en constante amélioration 

comparaison apps pwa

Comme vous pouvez le voir, les technologies autour de PWA permettent une prise en compte des fonctionnalités des apps natives.  

Une application web classique peut facilement devenir une progressive web app en lui ajoutant les fonctionnalités nécessaires, mais ce n’est pas toujours pertinent en fonction des applications. De la même manière, en fonction du type d’application, il faudra faire le bon choix et s’orienter sur la meilleure méthode selon son contexte. 

 

les PWA en detail 

Progressive enhancement 

L’amélioration progressive est un principe de conception de site web. Il prend en compte les fonctionnalités de base auxquelles ont accès l’ensemble des utilisateurs, et propose des fonctionnalités plus récentes à ceux qui utilisent les navigateurs les plus modernes (notamment les navigateurs qui prennent en compte les nouveautés autour de PWA). 

Le site web va devoir détecter les fonctionnalités compatibles avec le navigateur afin de proposer à l’utilisateur que ce qui fonctionne dans sa situation. En effet, au-delà des fonctionnalités du navigateur, c’est aussi le type d’appareil qu’il utilise, la performance de sa connexion internet et sa situation qui seront étudiées pour lui proposer la meilleure expérience possible. Toutefois, l’invention du terme PWA vient avec un nombre précis de fonctionnalités que nous allons maintenant parcourir. 

Responsive 

Une PWA est utilisable sur différents périphériques : ordinateur, tablette et smartphone. C’est ainsi une application web responsive qui s’adapte aux différentes résolutions des supports sur lesquels elle peut être installée.  

Le responsive c’est aussi la bonne utilisation des medias queries qui permettent de proposer une mise en page adaptée en fonction des différentes tailles d’écran, résolution, orientation… Le responsive est déjà de l’amélioration progressive. En fonction du contexte d’accès de l’utilisateur, son expérience va changer car le site s’adaptera à son périphérique. Au-delà de la vue et du positionnement des blocs, c’est le contenu ou sa qualité qui peut changer, notamment pour les images. 

En général, lorsque l’on parle de responsive, on évoque les grilles. En effet, celles-ci vous permettent de réaliser des interfaces responsives de manière plus optimale. Plusieurs techniques existent pour développer des grilles : la méthode la plus ancienne est la structure en float et pourcentage, puis on a vu l’apparition des flexboxs permettant de faciliter les positionnements de blocs. Cependant, ce n’était que des détournements de fonction. Maintenant, une technologie de CSS Grid dédiée existe. Afin de prendre en compte l’ensemble des navigateurs, il faudra mettre en place une amélioration progressive. Pour cela on pourra utiliser le style suivant pour conditionner l’utilisation de propriété en fonction de la prise en charge du navigateur : 

@supports(display: grid) { 
   /*Grid CSS Stuff*/ 
}

Connexion hors-ligne

Une PWA est utilisable hors ligne grâce à la technologie de « services worker » qui permet de sauvegarder les fichiers au niveau du navigateur. Aussi, après une première connexion, les contenus téléchargés seront accessibles sans que l’on ait besoin d’être connecté au web. 

Pour gérer cet accès hors ligne, il faudra dans un premier temps contrôler si le navigateur prend en compte la fonctionnalité et souscrire au service worker : c’est la phase d’enregistrement. 

if ('serviceWorker' in navigator) { 
    navigator.serviceWorker.register('/sw.js').then(function(reg) { 
        // registration worked 
        console.log('Registration succeeded. Scope is ' + reg.scope); 
    }).catch(function(error) { 
        // registration failed 
        console.log('Registration failed with ' + error); 
    }); 
} 

Une fois enregistré, il faudra l’installer. On va donc s’intéresser au contenu du fichier sw.js.
Dans un premier temps, celui-ci doit permettre l’installation. Aussi, un écouteur d’événement « install » est ajouté au service worker. Ensuite, la méthode waitUntil va attendre la bonne exécution du code qu’elle contient afin d’installer le service worker. Dans ce code, on peut retrouver la mise en cache via « caches » et la méthode « addAll » de différents contenus comme ci-dessous : 

this.addEventListener('install'function(event) { 
    event.waitUntil( 
        caches.open('v1').then(function(cache) { 
          return cache.addAll([ 
              '/index.html', 
              '/style.css', 
              '/app.js', 
          ]); 
        }) 
    ); 
}); 

Si la promesse est un succès, l’activation du service worker sera effective. Nous avons donc bien des fichiers en cache. Cependant, il faudra capturer les requêtes afin d’aller chercher les ressources via le service worker au lieu du serveur. On utilisera donc l’événement « fetch » et la méthode « respondWith » pour détourner les requêtes http.  

Avec « caches.match(event.request) » on peut simplement faire correspondre les ressources distantes avec celles en cache lorsqu’elles existent. 

  this.addEventListener('fetch'function(event) { 
    event.respondWith( 
        caches.match(event.request) 
    ); 
  }); 

De nombreux paramètres sont bien entendu possibles pour gérer le service worker, et nous avons vu les plus importants. 

InteractionS comme sur une app native

Une PWA propose une expérience au plus proche d’une application native, que ce soit dans la navigation ou les interactions. Par conséquent, une PWA doit utiliser un shell d’application, c’est-à-dire un code de base qui offre un chargement rapide ainsi qu’une mise en cache et un chargement des contenus de manière dynamique. Le shell d’application comporte l’ensemble des fonctionnalités HTML, CSS et JavaScript essentielles au démarrage de l’application et permettant les premières interactions. 

En général, pour réaliser une PWA, on utilisera les librairies et frameworks front-end, ceux-ci proposant une organisation en composant et permettant de mettre en place facilement un shell d’application. 

Mise à jour d’une PWA

Une PWA comporte un contenu mis à jour régulièrement grâce au processus de mise à jour du service worker. Pour mettre à jour le service worker, nous allons ajouter dans le cache une nouvelle version du contenu comme cela a été fait la première fois. On peut par la suite choisir de supprimer l’ancienne version via la méthode « delete » comme lors de l’activation (événement qui a lieu après l’installation) : 

 self.addEventListener('activate', (event=> { 
  var cacheKeeplist = ['v2'];  

  event.waitUntil( 
    caches.keys().then((keyList=> { 
      return Promise.all(keyList.map((key=> { 
        if (cacheKeeplist.indexOf(key=== -1) { 
          return caches.delete(key); 
        } 
      })); 
    }) 
  ); 
}); 

Sécurité

Une PWA est sécurisée puisqu’elle est accessible uniquement en HTTPS grâce au certificat SSL. Ça peut être assez fastidieux à mettre en place sur un environnement de développeur local, car il faudra créer un certificat auto-signé puis supprimer les blocages de sécurité sur les navigateurs. 

Exemple de génération via OpenSSL : 

 openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 

Ouverture de Chrome sans la sécuritésur un Mac  

 /Applications/GoogleChrome.app/Contents/MacOS/GoogleChrome --ignore-certificate-errors &> /dev/null  

Reconnaissance en tant qu’application

Une PWA est reconnue comme une application via un fichier manifest.json qui informe sur l’application et fournit sa configuration. La PWA est aussi enregistrée auprès du service worker comme une application. Voici un exemple de fichier manifest qui est proposé dans ReactJS. Ce fichier est associé à l’html via une balise link :  

<link rel="manifest" href="/manifest.json"> 

Comme vous pouvez le voir, il permet de décrire le fonctionnement de l’application, son titre, ses icones, l’url d’accès, le mode (en général pour masquer la barre d’adresse), la couleur du thème pour modifier la couleur de la barre native et la couleur du fond. 

Manifest.json 
{ 
  "short_name""React App", 
  "name""Create React App Sample", 
  "icons": [ 
    { 
      "src""favicon.ico", 
      "sizes""64x64 32x32 24x24 16x16", 
      "type""image/x-icon" 
    }, 
    { 
      "src""logo192.png", 
      "type""image/png", 
      "sizes""192x192" 
    }, 
    { 
      "src""logo512.png", 
      "type""image/png", 
      "sizes""512x512" 
    }   
  ], 
  "start_url"".", 
  "display""standalone", 
  "theme_color""#000000", 
  "background_color""#ffffff" 
}

Il permet aussi de générer un écran de lancement de l’application avec l’icône, le titre, et la couleur de fond.
Les propriétés du manifest ne sont pas prises en compte par iOS actuellement; toutefois, certaines peuvent être intégrées via des balises « link », notamment les icons pour différentes résolutions :

<link rel="apple-touch-icon" href="touch-icon-iphone.png"> 
<link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad.png"> 

Pour le splashscreen, on peut en créer un spécifique via :  

<link rel="apple-touch-startup-image" href="/launch.png"> 

Si vous voulez spécifier le nom de l’application :  

 <meta name="apple-mobile-web-app-title" content="AppTitle"> 

Pour activer le mode standalone sans la navigation on utilisera :  

<meta name="apple-mobile-web-app-capable" content="yes"> 

Et pour changer l’apparence de la barre native :  

<meta name="apple-mobile-web-app-status-bar-style" content="black"> 

Notifications push

Une PWA utilise des notifications push pour transmettre des informations à l’utilisateur, même s’il n’est pas connecté à l’application. Ce dernier sera alors prévenu d’une nouvelle actualité ou d’un changement sur l’application.
Toute notification sur un navigateur est directement accesible via « windows.navigation ». On trouve ensuite différentes méthodes pour gérer des notifications. 

Voici un exemple où on va demander à l’utilisateur sa permission via « Notification.requestPermission() » puis lui envoyer une notification via « showNotification » :    

  Notification.requestPermission(function(result) { 
    if (result === 'granted') { 
      navigator.serviceWorker.ready.then(function(registration) { 
        registration.showNotification('Notifs me !', { 
          body: 'On reste en contact.', 
          icon: '../images/favicon/apple-icon-180x180.png', 
          vibrate: [200100200100200100200], 
          tag: 'test',  

        }); 
      }); 
   } 
  }); 

Sur les notifications, la complexité ne réside pas dans la création de la notification push en JavaScript, mais plutôt dans les batchs à faire tourner pour envoyer des notifications. En effet, les batchs devront savoir à qui eà quels moments envoyer la notification et ce qu’elles devront contenir. 
Sur iOS, cela reste non fonctionnel pour le moment. 


Installation

Une PWA est installable sur le périphérique utilisé. Pour cela, elle propose un moyen à l’utilisateur d’installer l’application sur son écran d’accueil. Comme nous l’avons vu, via le manifest, une PWA est reconnue comme une application. Pour l’ajouter à son écran d’accueil pour en faire une app à part entière consultable hors ligne et sans les éléments de navigation, il faut faire quelques petites actions. 
Le manifest doit contenir un lien vers une icône pour l’affichage sur l’écran d’accueil. Il est également important d’être en HTTPS et d’avoir le service worker d’installlé. Une fois cela effectué, on peut ajouter un élément graphique de type bouton dans une popin pour proposer l’installation de l’application. 

Il sera rendu visible via un événement « beforeinstallprompt » qui permet de prendre connaissance de la capacité d’installation de la PWA. On pourra ensuite associer l’événement pour afficher les fenêtres du navigateur par défaut via « deferredPrompt.prompt(); » et « deferredPrompt.userChoice » pour connaitre le choix de l’utilisateur. 

window.addEventListener('beforeinstallprompt', (e=> { 
  // Prevent Chrome 67 and earlier from automatically showing the prompt 
  e.preventDefault(); 
  // Stash the event so it can be triggered later. 
  deferredPrompt = e; 
  // Update UI to notify the user they can add to home screen 
  addBtn.style.display = 'block';  

  addBtn.addEventListener('click', (e=> { 
    // hide our user interface that shows our A2HS button 
    addBtn.style.display = 'none'; 
    // Show the prompt 
    deferredPrompt.prompt(); 
    // Wait for the user to respond to the prompt 
    deferredPrompt.userChoice.then((choiceResult=> { 
        if (choiceResult.outcome === 'accepted') { 
          console.log('User accepted the A2HS prompt'); 
        } else { 
          console.log('User dismissed the A2HS prompt'); 
        } 
        deferredPrompt = null; 
      }); 
  }); 
});

Sur iOS, cet événement n’existe pas. Iest nécessaire d’indiquer dans une fenêtre informative comment ajouter l’application PWA à l’écran d’accueil. Cela se fait en passant par les options de partage et le bouton « ajouter à l’écran d’accueil ».  

 

Hyperlien (Linkable) et autres fonctionnalités

Une PWA est partageable via une url car elle reste un site web, et le cœur du web reste l’hyperlien. Une PWA reste un site web et donc il reste partageable et accessible via le web. Finalement c’est toutes les améliorations progressives qui pourraient être incluses dans la notion de PWA. Autour du concept, on évoque souvent la performance et l’accès aux nombreuses technologies des différents périphériques qu’on utilise. 

 

Les outils autour des PWA 

Il existe de nombreux outils développés notamment par Google. Parmi eux on retrouve Workbox, une librairie simplifiant la gestion des services workers. 
Avec l’outil d’audit de Chrome, Lighthouse, accessible dans le devToolsvous pouvez analyser les fonctionnalités d’un site web pour connaitre les fonctionnalités qu’il prend en compte par rapport aux PWA. 

Lighthouse

Lorsque vous voulez réaliser une PWA, utilisez Lighthouse pour mettre en place les fonctionnalités manquantes au fur et à mesure. 

L’ensemble des librairies et frameworks ont mis en place les fonctionnalités PWA ; on pourra simplement implémenter une PWA sur React, Vue, Angular et globalement l’ensemble des librairies et frameworks JS modernes. React, par exemple, génère par défaut le service worker et propose un manifest. Vue et Angular proposent aussi des implémentations pour l’offline et le manifest. 

Cependant, c’est pour les notifications qu’il y a beaucoup de choses à faire, et ça n’est pas implémenté car cela demande une couche back et serveur importante. 

 

Actuellement, on rencontre souvent le choix de l’hybride qui permet avant tout de mutualiser sur une technologie précise. Les applications natives restent toutefois plus pertinentes dans de nombreux cas, et les progressive web apps viennent s’ajouter à la liste car elles sont aussi très appréciables sur certains types d’applications. Ce qui est intéressant, c’est que la PWA est progressive et va au fur et à mesure de la prise en compte des navigateurs : leurs nouvelles fonctionnalités diverses vont venir concurrencer les applications natives, et peut être même aller au-delà. 

 


Liens utiles

Pour connaitre les fonctionnalités compatibles avec votre navigateur : 

Comme todoMVC pour les applications JavaScript en MV*, HNPwa permet de visualiser les tests des fonctionnalités PWA avec la même application mais réalisé avec différents frameworks et librairies ou en natif.  https://hnpwa.com/ 

0 commentaires

votre commentaire

Se joindre à la discussion ?
Vous êtes libre de contribuer !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Inscription newsletter

Ne manquez plus nos derniers articles !