PROGRESSIVE WEB APPS : OVERVIEW

PROGRESSIVE WEB APPS : OVERVIEW

Le mobile se caractérise de nos jours par une grande diversité de terminaux et de systèmes d’exploitation. Rien que du côté Android, les variations ont de quoi donner mal à la tête. Si on rajoute à ça les applications disponibles sur chaque machine pour aller sur le Web, le nombre de combinaisons à gérer devient colossal. Taille de l’écran, OS, navigateur, type de connexion sont les principaux paramètres à prendre en compte quand on développe son app, mais pas forcément les seuls. Nous allons voir dans ce dossier comment tenter de dompter tout ça grâce aux progressive web apps.

L’implémentation d’un projet mobile commence par le choix de la technologie employée. En fonction de cette décision, les approches seront radicalement différentes. Souhaite-t-on se positionner au plus près du système d’exploitation ou toucher un maximum de plateformes différentes ? Le but est-il d’avoir les meilleures performances pures ou plus de flexibilité, de facilité à réaliser des portages entre les différents OS ? Quid du déploiement et des mises à jour, des aspects qui varient grandement en fonction de la stratégie choisie. Les questions à se poser avant d’attaquer la moindre ligne de code sont nombreuses et cruciales pour la suite.

pwa-02

Développement natif

Le natif permet de développer une application adaptée aux devices ciblés. Il faut utiliser le langage de la plateforme (Swift pour iOS par exemple, Java pour Android). Cette proximité fait que l’application aura accès à un maximum de fonctionnalités de l’appareil et sera la plus performante. Il faut évidemment multiplier les développements par autant de systèmes ciblés dans la mesure où le code produit n’est pas réutilisable. Enfin, le déploiement ne passe que par les stores propriétaires de chaque marque, ce qui alourdit le mécanisme de mise à jour.

pwa-03

L’option Web App

Radicalement différente, cette approche mise plutôt sur la production de code générique. En effet, on développe une application Web, exécutable dans un navigateur moderne. Le code utilise les standards classiques du Web : HTML, JS et CSS. Les évolutions sont directement accessibles après leur déploiement.

pwa-04

Le développement hybride

Le développement hybride se propose de marier les deux approches précédentes en proposant :

  • Une base de code Web, donc multiplateforme, et une API d’accès aux fonctionnalités natives.
  • Un conteneur natif.

Le schéma ci-dessous synthétise les différentes options :

pwa-05

Progressive Web Apps : les concepts

Description

Les PWA tentent d’unifier ces différentes approches en améliorant l’expérience utilisateur. L’idée est de booster une application Web pour lui offrir des capacités jusque-là réservées au monde du natif. Ainsi on pourra à partir du navigateur :

  • Installer l’application
  • Travailler en mode déconnecté
  • Recevoir des notifications (même si l’application ne tourne pas)

pwa-06

Mais ça reste une application Web qui utilise les standards (HTML, CSS et JS) et qui hérite donc de la capacité à être :

  • Responsive pour s’adapter facilement aux différentes tailles d’écrans
  • Trouvable par l’intermédiaire des moteurs de recherche. C’est en effet plus fastidieux d’indexer et de chercher dans les stores une application native.
  • Adressable, car on peut aisément pointer sur un état particulier de l’application à l’aide d’URL.

Dernier avantage, l’application sera toujours à jour.

Le maitre mot reste le côté PROGRESSIF. En effet pour arriver à ce résultat, nous verrons que nous utiliserons des fonctionnalités qui ne sont pas supportées par tous les navigateurs. L’idée est de proposer une application Web qui fonctionne partout, et de l’améliorer de façon progressive, sans altérer le code de base.

Nous pourrons ainsi :

  • Offrir davantage à l’utilisateur si son navigateur le permet.
  • Quel que soit le navigateur, l’application doit fonctionner et offrir la meilleure expérience possible.

Pré-requis

Afin de mettre en place ces concepts, nous devons respecter certaines conditions. Tout d’abord, notre application ne peut être accessible qu’en HTTPS pour garantir la sécurité de nos échanges. De plus en plus, de nouvelles API comme la géolocalisation ou l’accès aux médias imposent également cette contrainte.

pwa-07

Rassurez-vous, en phase d’implémentation, le fameux localhost sera considéré comme HTTPS, et il est possible de tester ses développements facilement. Pour le déploiement, nous pouvons utiliser :

  • des plateformes qui utilisent nativement le HTTPS comme GitHub, App Engine ou Heroku.
  • un certificat gratuit renouvelable tous les 6 mois via Let’s Ecrypt.

Un autre impératif est d’utiliser le responsive design, pour s’assurer que l’application s’affichera dans les meilleures conditions, quelle que soit la taille d’écran du téléphone. C’est important de la rappeler, même si cette technique devient commune aujourd’hui. Pour vous simplifier la tâche, vous pouvez utiliser des frameworks CSS comme boostrap ou d’autres à base de Material Design.

Les services workers

Définition

Le chef d’orchestre qui vous permettra de booster votre application web est le service worker. Il s’agit d’un web worker qui :

  • s’exécute dans un thread différent de votre page web
  • n’a pas accès au DOM

pwa-08

Il possède ces caractéristiques, car il s’agit en fait d’un proxy qui :

  • Intercepte l’ensemble des requêtes du navigateur
  • Dispose d’un accès à une API de cache
  • Dispose d’un accès à une API de fetch pour gérer les requêtes

Pour pouvoir l’utiliser dans votre application, vous allez devoir tester son support dans le navigateur puis l’enregistrer :

if ('serviceWorker' in navigator) 
  navigator.serviceWorker.register('your-file.js') 
.then(function() {
 console.log('Register SW'); 
}); 
}

L’ensemble du code de notre service worker sera dans un fichier indépendant, que nous allons enregistrer. Il est là, le coté progressif. Ce code n’affectera pas les navigateurs qui n’utilisent pas encore la méthode register.

Événements et cycle de vie

Une fois le service worker installé, nous disposerons de plusieurs événements pour gérer notre application. La première chose à savoir est que nous utiliserons le mot clé self pour référencer le service worker dans son code. Ainsi pour écouter les différents événements nous utiliserons le code suivant :

self.addEventListener('event-name', function(event){
}); 

Il faut au préalable distinguer les évènements du cycle de vie des événements fonctionnels :

pwa-09

Le cycle de vie d’un service worker suit le processus ci-dessous

  • L’enregistrement comme vu précédemment. Le service worker entre alors dans une phase d’installation. Un événement install est dispatché.

pwa-10

  • Une fois installé, le service worker attend que les anciens services workers ne soient plus utilisés. Il faut en effet que les pages qui les ont initiés se ferment pour que le nouveau service puisse prendre la main.

pwa-11

  • Le service worker va alors être activé. Nous aurons la main en écoutant l’événement activate.

pwa-12

  • Activé, le service worker est désormais prêt à écouter les requêtes du navigateur.

pwa-13

En réponse à ces différents événements, nous allons pouvoir effectuer un certain nombre d’actions. Nous pouvons par exemple utiliser la méthode waitUntil pour :

  • Sur l’événement install, appeler la méthode self.skipWating() pour forcer notre service worker en attente à devenir le service actif.
  • Sur l’événement activate, appeler la méthode self.clients.claim() pour forcer les clients ouverts à utiliser notre service worker maintenant actif.

Fetch API

Une fois activé notre service worker va désormais écouter les requêtes et y répondre par un événement fetch. Nous pourrons alors intervenir en utilisant la méthode respondWith de l’événement.

pwa-14

self.addEventListener('fetch', function(event)
  event.respondWith(
  	fetch(event.request).then(function(responseFetch){
 return responseFetch; 
}) 
  ); 
});

Il faut distinguer :

  • l’événement fetch qui contient les informations sur la requête (event.request.url).
  • la méthode de fetch API qui permet d’effectuer une requête de façon asynchrone. Cette API propose également des constructeurs Response et Request. Nous pouvons ainsi modifier complètement la requête ou la réponse.

Cache API

Pour aller plus loin et optimiser les performances de notre application, nous allons utiliser l’API de cache. Il s’agit d’enregistrer localement dans un cache dédié (différent de celui du navigateur) les ressources que nous souhaitons rendre disponibles le plus rapidement possible.

À l’installation

L’événement install est le bon moment pour enregistrer dans le cache les fichiers souhaités.

pwa-15

Pour cela nous pouvons :

  • ouvrir un cache identifié par un nom avec la méthode open
  • ajouter des ressources identifiées par leur chemin avec la méthode addAll
caches.open('v1').then(function(cache) {
  return cache.addAll([
'/', 
'/index.html', 
'/style.css', 
	'/app.js', 
... 
  ]); 
})

Le service worker va alors chercher les ressources sur le réseau et enregistrer la réponse du serveur dans le cache.

À l’activation

Cette phase correspond au bon moment pour nettoyer le cache et éventuellement effacer les ressources d’anciennes versions de notre application.

pwa-16

À l’exécution

Ces ressources seront maintenant accessibles à notre service worker. Il pourra par exemple en réponse à un événement fetch, chercher dans le cache si le fichier demandé est présent avec la méthode match.

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

On commence à entrevoir différentes stratégies de caches possibles :

Cache first

pwa-17

Le service worker en réponse à la requête essaie de la localiser d’abord dans le cache. En cas d’échec, il demandera alors la ressource au serveur.

self.addEventListener('fetch', function(event) {
  event.respondWith(
  	caches.match(event.request).then(function(response) {
 return response || fetch(event.request); 
  	}); 
  ); 
});

Cache sur réponse

pwa-18

Dans cette situation, c’est au contraire le réseau qui est d’abord sollicité et la réponse est retournée à la page, mais également ajoutée au cache (à l’aide la méthode put).

self.addEventListener('fetch', function(event) {
 event.respondWith(
 fetch(event.request).then(function(response) {
 return caches.open('v1').then(function(cache) {
 cache.put(event.request, response.clone()); 
 return response; 
	}); 
}) 
	) 
});

Attention, une réponse ne peut être consommée qu’une seule fois. Donc si on la retourne à la page il faut alors la cloner pour en disposer dans le cache. Nous pouvons évidemment combiner les stratégies ou en utiliser d’autres.

Une stratégie offline fallback par exemple, consiste à fournir un contenu alternatif si la ressource souhaitée n’est pas dans le cache et si nous sommes déconnectés.

e.respondWith(
 caches.match(e.request) 
	.then(function(response) {
 return response || fetch(e.request); 
	}) 
.catch(function() {
 return caches.match('/offline.html'); 
}) 
);

Le traitement se fait alors dans le catch car effectivement l’absence de réseau provoquera une exception sur les requêtes. La ressource offline.html aura été ajoutée préalablement durant une phase d’installation.

Ressources :

Mozilla / Jakearchibald / Google

Instant loading et performance

On sait maintenant comment intervenir sur les requêtes de notre application. Mais à quoi cela va-t-il servir ? En fait, tout est une question de performance. En effet, nous savons que les utilisateurs de notre application ne tolèreront pas une page blanche qui met trop de temps à se charger. Cette “impatience” est encore plus marquée pour une application native. Nous devons donc veiller à proposer à l’utilisateur le plus rapidement possible (voir immédiatement) du contenu.

L’app shell

Pour cela nous devons nous demander

  • qu’est-ce qui doit apparaître à l’écran immédiatement ?
  • Quels sont les composants clés de notre application ?
  • Quelles sont les ressources dont nous avons besoin ? (images, css, js, etc.)

C’est en répondant à ces questions que nous allons définir l’app shell.

Il s’agit du HTML, CSS et JavaScript minimum pour obtenir l’interface utilisateur. L’application JavaScript se chargera alors de remplir cette coquille avec des données.

pwa-19

Nous utiliserons les API vu précédemment pour cacher ces ressources et les fournir au chargement de la page avec :

  • La mise en cache et suppression du cache sur les événements install et activate
  • La stratégie cache first pour les ressources de l’application shell

Ressources :

GitHub / Google Dev

Bonnes pratiques

Il existe de nombreuses pratiques destinées à rendre les applications web plus performantes, au-delà du cadre des PWA. La liste ci-dessous n’est bien sûr pas exhaustive :

  • Compression des assets
  • Utilisation de asynch/defer pour les scripts

pwa-20

  • Chargement asynchrone des CSS non critiques
  • Bonne gestion des entêtes du cache navigateur
  • Utilisation d’HTTP2
  • Éviter les phases de layout et de paint comme par exemple en utilisant la propriété CSS transform (https://csstriggers.com/)
  • etc.

Installation

Nous avons maintenant une application performante capable de délivrer du contenu en mode déconnectée. Comment indiquer que nous voulons la rendre éligible à l’installation. Nous parlons ici de véritable installation, et non de simple raccourci. En effet l’application se lancera avec un splash screen, en mode plein écran dans un conteneur autonome. Elle apparaitra dans le task switcher de notre système d’exploitation.

Manifest.json

Pour permettre tout cela, nous allons devoir associer à l’application un fichier manifeste, qui contiendra les caractéristiques de l’app.

Pour associer ce fichier à la page il suffit d’utiliser une balise link :

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

Il s’agit d’un fichier JSON qui contient les propriétés suivantes :

{
 "name": "Peoples",
 "short_name": "Peoples",
 "icons": [
   {
     "src": "../img/icons/icon-192x192.png",
     "sizes": "192x192",
     "type": "image/png"
   }
  ],
 "start_url": "index.html",
 "display": "standalone",
 "orientation": "portrait",
 "background_color": "#3E4EB8",
 "theme_color": "#2F3BA2",
 "gcm_sender_id": "xxxx"
}
  • short_name sera utilisé pour indiquer le nom de l’application.
  • icons fait référence à l’image à utiliser pour l’écran d’accueil et le splash screen.
  • Background_color et theme_color serviront à définir respectivement la couleur de fond du splash screen et celle de la barre d’état.
  • Start_url identifie le premier écran.
  • Display permet d’indiquer si on souhaite lancer l’application en plein écran (standalone) ou en mode navigateur (browser).
  • Orientation indique l’orientation à utiliser (portrait ou paysage)

Processus d’installation

Nous allons voir maintenant comment le processus d’installation se met en place. Pour que le navigateur propose à l’utilisateur automatiquement une bannière d’installation, il y a trois conditions :

  • Il y a un service worker
  • Il y un manifeste valide
  • L’utilisateur a fait au moins deux visites en l’espace de 5 minutes

Si ces conditions sont respectées, une bannière d’installation est proposée, qui reprend le nom et l’icône indiqués dans le manifeste.

pwa-21

Et en JavaScript

Même si vous ne pouvez pas déclencher cette installation, vous avez quand même l’opportunité d’interagir avec l’événement beforeinstallprompt.

window.addEventListener('beforeinstallprompt', function(e) {
   //Do something 
});

Vous pouvez à partir de là :

  • Connaître le choix de l’utilisateur par l’intermédiaire de la propriété userchoice de l’événement
window.addEventListener('beforeinstallprompt', function(e) {
	e.userChoice.then(function(choiceResult) {
    	if(choiceResult.outcome == 'dismissed') {
        	console.log('User cancelled home screen install');
    	}
    	else {
        	console.log('User added to home screen');
    	}
	});
});
  • Annuler l’installation en utilisant la méthode preventDefault.
window.addEventListener('beforeinstallprompt', function(e) {
	e.preventDefault();
	deferredPrompt = e;
	return false;
});

Cela permet par exemple de lancer l’installation sur une action de l’utilisateur. Il faut pour cela utiliser la méthode prompt de l’événement que vous aurez préalablement enregistré dans une variable.

btnSave.addEventListener('click', function() {
	...
	deferredPrompt.prompt();

});

Les notifications

À l’aide des notifications, nous allons pouvoir améliorer le réengagement vers notre application. En effet, nous disposons d’un mécanisme pour envoyer des messages pertinents à l’utilisateur, pour le rediriger vers l’application, même si elle n’est pas affichée dans le navigateur. La réalisation s’effectue en trois étapes qui font intervenir trois acteurs :

  • La push API qui permet à une application web de recevoir des messages poussés par un serveur.
  • La notification API qui permet d’afficher des notifications en dehors du contexte du navigateur.
  • Un service de Web Push pour faire le proxy entre votre serveur et le navigateur.

La souscription

pwa-22

Vous allez tout d’abord devoir demander à l’utilisateur s’il accepte de recevoir des notifications de la part de votre application. L’ensemble des méthodes utilisées sera disponible par l’intermédiaire d’un pushManager accessible à la suite de l’enregistrement de notre service worker.

Ainsi, dans l’application, vous allez d’abord vérifier si l’utilisateur est abonné aux notifications. Nous demandons les souscriptions courantes au pushManager à l’aide de sa méthode getSubscription.

navigator.serviceWorker.register('/service-worker.js')
.then(function(reg) {
	reg.pushManager.getSubscription()
        	.then(function(sub) {
            	console.log('Subscription Info', sub);
        	});
});

Si l’utilisateur n’est pas inscrit, nous pouvons lui demander de s’abonner (en réponse à un clic de bouton par exemple) :

function subscribe() {
  reg.pushManager.subscribe({userVisibleOnly: true})
	.then(function(pushSubscription){
  	sub = pushSubscription;
  	console.log('Subscribed! Endpoint:', sub.endpoint);
	});
}

Une fenêtre lui sera alors proposée pour lui demander son accord.
pwa-23

Chaque navigateur dispose d’un serveur central pour lui envoyer des notifications. Vous allez donc devoir passer par ce serveur central pour envoyer vos messages. Lorsque l’utilisateur accepte de recevoir des notifications vous récupérez alors les informations vers ce serveur dans la propriété endpoint. Vous pouvez alors l’enregistrer sur votre propre serveur pour une utilisation ultérieure.

Nous pouvons aussi proposer un désabonnement :

function unsubscribe() {
  sub.unsubscribe().then(function(event) {
	console.log('Unsubscribed!', event);
  });
}

Envoyer des messages

Pour envoyer un message vous allez devoir contacter le end point.

 

pwa-24

Pour Chrome, il faut passer par le Google Cloud Messaging (GCM). Vous allez devoir vous créer un projet sur la console Google Developper et activer les API GCM. Vous pourrez alors activer l’API GCM et récupérer la clé d’utilisation. L’id du projet devra être ajoutée à votre manifeste dans la propriété gcm_sender_id

pwa-25

{   …
  "gcm_sender_id": "593xxxxxxxxx"
} 

Nous allons maintenant pouvoir envoyer des requêtes GCM qui contiennent :

  • La clé d’API public
  • Un entête content-type de type application/json
  • Un tableau d’id de souscriptions (endpoint récupéré lors de l’abonnement) pour identifier les applications.
curl --header "Authorization: key=XXXXXXXXXXXX" --header "Content-Type: application/json" https://android.googleapis.com/gcm/send -d "{\"registration_ids\":[\"fs...Tw:APA...SzXha\"]}"

En phase de développement nous pourrons utiliser les outils chrome pour simuler une notification et tester notre code :

pwa-26

Il existe d’autres plateformes pour envoyer des push notifications comme :

Ressources :

Google / W3C / Notification Specs

Afficher des messages

La dernière étape consiste à afficher un message à l’utilisateur.

pwa-27

C’est encore le service worker qui va intervenir en écoutant l’événement push.

self.addEventListener('push', function(event) {
	event.waitUntil(
  	  self.registration.showNotification('Title', {
        	body: 'I\'m the message body',
        	icon: 'images/icons.png',
        	tag: 'tag'
    	})
	);
});

Nous utilisons alors la méthode showNotification en lui passant :

  • un message dans la propriété body
  • une image dans la propriété icon
  • des informations supplémentaires grâce à la propriété tag. Celles-ci ne seront pas affichées.

pwa-28

Nous pouvons aussi contacter notre serveur pour ajouter des données dynamiques :

self.addEventListener('push', function(event) {
	event.waitUntil(
    	fetch('/notification.json').then(function(response) {
        	return response.json();
    	}).then(function(data) {
        	self.registration.showNotification(data.title, {
            	body: data.body, icon: data.avatar, tag: data.mail
        	});
    	})
	);
});

Nous pouvons également proposer des choix à l’utilisateur :

self.registration.showNotification(data.title, {
	body: data.body,
	icon: data.icons,
	tag: data.tag,
	actions: [
    	{action: 'open', title: 'Show me more details'},
    	{action: 'cancel', title: 'No thanks'}
	]
});

Nous pouvons gérer la réponse de l’utilisateur en écoutant l’événement notificationclick :

self.addEventListener('notificationclick', function(event) {
	var url;
	event.notification.close();
	if (event.action === 'open') {
    	url = 'http://localhost:8080/' + event.notification.tag;
	}
	clients.openWindow(url);
});

Nous connaissons l’action de l’utilisateur grâce à la propriété action de l’événement et nous pouvons alors ouvrir l’application en appelant la méthode client.openWindow avec la bonne url. Notez l’appel à event.notification.close. En effet, le navigateur ne ferme pas la notification automatiquement, vous devez donc vous en charger. On remarque également que nous pouvons ici utiliser la propriété tag pour y stocker des informations utilise comme un id par exemple, qui pourra être réutilisé pour accéder au bon état de l’application.

Le futur

Les PWA ouvrent incontestablement de nouveaux horizons pour le développement de projets mobiles. Elles ne pourront pas complètement remplacer les applications natives, mais représentent une alternative intéressante pour améliorer progressivement l’expérience utilisateur pour certains usages. On peut imaginer qu’une société réserve les applications natives aux utilisateurs fidélisés, avec une panoplie de services personnalisés. Ces utilisateurs font la démarche de rechercher l’application dédiée dans le store de leur smartphone. Au contraire, une PWA pourra cibler les utilisateurs occasionnels, par l’intermédiaire du site, et leur proposer des services utiles en améliorant leur expérience. L’objectif étant de les fidéliser, pour ensuite les conduire à utiliser l’application native. Dans le même esprit, les PWA pourront être réservées à des applications événementielles.

Mais cette distinction s’amenuise de plus en plus. On peut même se demander si elle sera encore d’actualité dans le futur :

pwa-29

Nous pouvons voir dans le tableau ci-dessus que de plus en plus de fonctionnalités sont désormais communes aux plateformes web et natives.

Mais élargissons un peu les horizons. La plateforme web est en pleine ébullition et on voit arriver de grandes opportunités.

De nouvelles API

De nouvelles API arrivent pour encore faciliter l’utilisation des applications. L’objectif est toujours l’amélioration de l’expérience utilisateur.

Connaître ses utilisateurs

Il n’y a rien de plus fastidieux que de remplir un formulaire sur un terminal mobile. Nous pouvons y remédier en nous appuyant sur l’attribut autocomplete pour la réalisation de formulaires. En référençant le champ de saisie par un nom grâce à cet attribut, le navigateur saura pré-remplir ces champs dans une utilisation future. Et grâce à des noms standardisés, Google et sa fonction autofill permettent également de partager ces profils (noms, adresse, carte de crédit, email, téléphone) pour remplir tout un formulaire.

Ressources.

Simplifier l’authentification

Les mots de passe sont de plus en plus nombreux, complexes et donc difficile à retenir. La Credentials Management API vous donnes un accès programmatique au manager de mot de passe du navigateur.

navigator.credentials.get({
	"password": true, "unmediated":
    	true
}).then(c => {
	if (!c) return;
	// Hooray, we have a credential!
	signInToYourApplication(c);
});

Vous pourrez ainsi enregistrer les informations d’authentification, les récupérer et proposer des profils d’authentification à l’utilisateur ou même automatiser le processus.

pwa-30

Ressources

Payment Request API

Dans le même esprit, cette API vous propose de simplifier le processus d’achat dans votre application. Vous pouvez créer une PaymentRequest contenant l’ensemble des informations nécessaires à la transaction (prix, mode de paiement, détails, etc.) Le navigateur présentera alors à l’utilisateur une fenêtre récapitulative.

pwa-31

Ressources

Web Bluetooth API

Grâce à cette API vous allez pouvoir interroger les appareils Bluetooth à proximité et interagir avec eux. Vous pourrez par exemple leur demander des informations sur leurs états et déclencher des actions.

navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
    	.then(device => device.gatt.connect())
.then(server => {
    	// Getting Battery Service...
    	return server.getPrimaryService('battery_service');
})
.then(service => {
    	// Getting Battery Level Characteristic...
    	return service.getCharacteristic('battery_level');
})
.then(characteristic => {
    	// Reading Battery Level...
    	return characteristic.readValue();
})
.then(value => {
    	console.log('Battery percentage is ' + value.getUint8(0));
})
.catch(error => { console.log(error); });

Ressources

Physical Web

Le principe consiste à déclencher une notification sur le téléphone de l’utilisateur dès qu’il est à proximité d’un beacon. Ce dernier broadcast par Bluetooth une url. Le navigateur informe l’utilisateur qui en cliquant peut alors être redirigé vers votre application.

pwa-32

Resources

Le web, la plate forme du future

Même si la plupart de ces nouvelles API sont encore au stade expérimental, on entrevoit les différentes interactions possibles. Un beacon pourra nous informer de la proximité d’un objet connecté. Notre PWA s’exécutera en mode déconnecté pour piloter cet objet via Bluetooth API par exemple. Les cas d’usages seront multiples :

  • proposer des informations supplémentaires lors de visites de musée
  • mettre à disposition les horaires de passage dans un arrêt de bus
  • proposer un paiement par Bluetooth à des parcmètres connectés
  • s’enregistrer dans une file d’attente de restaurant et être notifié quand notre table est prête
  • piloter des jouets
  • etc.

pwa-33

Support et compatibilité

Nous avons passé en revue les différentes fonctionnalités et API nécessaires pour la mise en place de PWA. Vous trouverez ci-dessous le support des ces API dans les différents navigateurs.

Service Worker

pwa-34

PUSH API

pwa-35

Notification API

pwa-36

Fetch API

pwa-37

Promise API

pwa-38

Web Bluetooth API

pwa-39

Credentials management API

pwa-40

On remarquera que la plupart des fonctionnalités ne sont actuellement disponibles que pour Chrome sous Android. Il faudra garder ce scope à l’esprit lors du choix d’implémentation, qui reste évidemment très limitant.

Toutefois nous avons des indicateurs très forts sur leurs implémentations dans l’écosystème Microsoft. La véritable problématique concerne le support des plateformes iOS. En effet, Safari n’implémente que peu d’API permettant la mise en place des PWA.

Physical Web

La fonctionnalité est disponible uniquement sur Chrome sur la plateforme Android ou iOS. Il faut toutefois prévoir une manipulation pour la rendre disponible.

Les outils

L’écosystème commence à s’enrichir pour les PWA et on commence à disposer d’outils pour faciliter leur mise en œuvre.

Les outils de débogage

Les outils Chromes proposent désormais un onglet dédié application qui vous permet d’explorer le cache, de simuler le mode déconnecté, d’envoyer des notifications, de débugger votre service worker, etc.

pwa-41

LightHouse

Ce plugin chrome va vous permettre d’auditer votre PWA. Il génère un rapport qui vérifie le respect des bonnes pratiques et fournit des métriques de performances.

Ressources

pwa-42

Sw-precache et sw-toolbox

Nous l’avons vu, l’écriture de code dans un service worker peut vite devenir fastidieuse. Ces outils vont vous permettre d’automatiser la mise en cache dans les scénarios les plus répandus.

pwa-43

Ressources

Les frameworks

Le concept de PWA est désormais relativement bien intégré dans :

  • Angular 2 : Angular-CLI permet en effet d’inclure automatiquement les différentes briques si le projet est généré avec le flag mobile. (Ressources)
  • Polymer : il existe un jeu de composant destiné à vous aider dans cette mise en place. (Voir ici et .)

Vous aimerez aussi...