Guide du débutant pour les applications Web progressives
A propos de l’auteur
Kevin Farrugia est un cofondateur d’Incredible Web, une société de développement d’applications mobiles web & basée à Malte, en UE ; qui fournit des …Plus d’informations surKevin↬
- 18 min de lecture
- Mobile,Apps,AMP,Service Workers
- Enregistré pour une lecture hors ligne
- Partager sur Twitter, LinkedIn
Les applications web progressives pourraient être la prochaine grande chose pour le web mobile. Proposées à l’origine par Google en 2015, elles ont déjà attiré beaucoup d’attention en raison de la relative facilité de développement et des gains presque instantanés pour l’expérience utilisateur de l’application.
Plus de lecture sur SmashingMag:
- Les blocs de construction des applications Web progressives
- Les essentiels du design conversationnel : Conseils pour construire un chatbot
- Construire une application de première classe qui tire parti de votre site Web
- Créer une application Web complète dans Foundation For Apps
Une application Web progressive tire parti des dernières technologies pour combiner le meilleur des applications Web et mobiles. Pensez-y comme un site Web construit à l’aide de technologies Web, mais qui agit et se sent comme une application. Les récentes avancées dans le navigateur et dans la disponibilité des travailleurs de service et dans les API Cache et Push ont permis aux développeurs web de permettre aux utilisateurs d’installer des applications web sur leur écran d’accueil, de recevoir des notifications push et même de travailler hors ligne.
Les applications web progressives tirent parti de l’écosystème web, des plugins et de la communauté beaucoup plus vaste et de la relative facilité de déploiement et de maintenance d’un site web par rapport à une application native dans les app stores respectifs. Pour ceux d’entre vous qui développent à la fois sur mobile et sur le web, vous apprécierez qu’un site web puisse être construit en moins de temps, qu’une API n’ait pas besoin d’être maintenue avec une compatibilité ascendante (tous les utilisateurs exécuteront la même version du code de votre site web, contrairement à la fragmentation des versions des apps natives) et que l’app soit généralement plus facile à déployer et à maintenir.
Pourquoi des Progressive Web Apps ?
Une étude a montré qu’en moyenne, une app perd 20% de ses utilisateurs pour chaque étape entre le premier contact de l’utilisateur avec l’app et le moment où l’utilisateur commence à utiliser l’app. Un utilisateur doit d’abord trouver l’application dans un magasin d’applications, la télécharger, l’installer et enfin, l’ouvrir. Lorsqu’un utilisateur trouve votre application web progressive, il peut immédiatement commencer à l’utiliser, ce qui élimine les étapes inutiles de téléchargement et d’installation. Et lorsque l’utilisateur revient à l’application, il sera invité à l’installer et à passer à une expérience plein écran.
Cependant, une application native n’a définitivement pas que des inconvénients. Les applications mobiles avec notifications push obtiennent jusqu’à trois fois plus de rétention que leurs homologues sans push, et un utilisateur est trois fois plus susceptible de rouvrir une application mobile qu’un site web. En outre, une application mobile bien conçue consomme moins de données et est beaucoup plus rapide, car certaines ressources résident sur l’appareil.
Une application web progressive tire parti des caractéristiques d’une application mobile, ce qui permet d’améliorer la rétention des utilisateurs et les performances, sans les complications liées à la maintenance d’une application mobile.
Cas d’utilisation
Quand faut-il construire une application web progressive ? Le natif est généralement recommandé pour les applications auxquelles vous vous attendez à ce que les utilisateurs reviennent fréquemment, et une application web progressive n’est pas différente. Flipkart utilise une web app progressive pour sa plateforme de commerce électronique populaire, Flipkart Lite, et les CFF utilisent une web app progressive pour leur processus d’enregistrement en ligne, permettant aux utilisateurs d’accéder à leurs billets sans connexion Internet.
Lorsque vous évaluez si votre prochaine application doit être une web app progressive, un site web ou une application mobile native, identifiez d’abord vos utilisateurs et les actions les plus importantes des utilisateurs. Étant » progressive « , une application web progressive fonctionne dans tous les navigateurs, et l’expérience est améliorée chaque fois que le navigateur de l’utilisateur est mis à jour avec des fonctionnalités et des API nouvelles et améliorées.
Donc, il n’y a aucun compromis dans l’expérience utilisateur avec une application web progressive par rapport à un site web traditionnel ; cependant, vous devrez peut-être décider des fonctionnalités à prendre en charge hors ligne, et vous devrez faciliter la navigation (n’oubliez pas qu’en mode autonome, l’utilisateur n’a pas accès au bouton retour). Si votre site web possède déjà une interface de type application, l’application des concepts des applications web progressives ne fera que l’améliorer.
Si certaines fonctionnalités sont nécessaires pour des actions critiques de l’utilisateur mais ne sont pas encore disponibles en raison d’un manque de support inter-navigateur, alors une application mobile native pourrait être la meilleure option, garantissant la même expérience pour tous les utilisateurs.
Caractéristiques d’une application web progressive
Avant de sauter dans le code, il est important de comprendre que les applications web progressives ont les caractéristiques suivantes :
- Progressives. Par définition, une web app progressive doit fonctionner sur n’importe quel appareil et s’améliorer progressivement, en tirant parti de toutes les fonctionnalités disponibles sur l’appareil et le navigateur de l’utilisateur.
- Découvrable. Parce qu’une application web progressive est un site web, elle doit pouvoir être découverte dans les moteurs de recherche. C’est un avantage majeur par rapport aux applications natives, qui sont toujours à la traîne par rapport aux sites Web en matière de facilité de recherche.
- Liable. Autre caractéristique héritée des sites web, un site web bien conçu devrait utiliser l’URI pour indiquer l’état actuel de l’application. Cela permettra à la web app de conserver ou de recharger son état lorsque l’utilisateur met en signet ou partage l’URL de l’app.
- Réactive. L’interface utilisateur d’une application web progressive doit s’adapter au facteur de forme et à la taille de l’écran de l’appareil.
- Similaire à une application. Une application web progressive doit ressembler à une application native et être construite sur le modèle de coquille d’application, avec un rafraîchissement minimal des pages.
- Indépendante de la connectivité. Elle doit fonctionner dans les zones de faible connectivité ou hors ligne (notre caractéristique préférée).
- Réengageable. Les utilisateurs d’applications mobiles sont plus susceptibles de réutiliser leurs applications, et les applications web progressives sont destinées à atteindre les mêmes objectifs grâce à des fonctionnalités telles que les notifications push.
- Installable. Une application web progressive peut être installée sur l’écran d’accueil de l’appareil, ce qui la rend facilement disponible.
- Fraîcheur. Lorsqu’un nouveau contenu est publié et que l’utilisateur est connecté à Internet, ce contenu doit être mis à disposition dans l’app.
- Sûre. Parce qu’une appli web progressive offre une expérience utilisateur plus intime et que toutes les requêtes réseau peuvent être interceptées par les travailleurs de service, il est impératif que l’appli soit hébergée sur HTTPS pour éviter les attaques de type man-in-the-middle.
Let’s Code!
Notre première appli web progressive, Sky High, simulera l’horaire des arrivées d’un aéroport. La première fois que l’utilisateur accède à notre application web, nous voulons lui montrer une liste des vols à venir, récupérée à partir d’une API. Si l’utilisateur n’a pas de connexion Internet et qu’il recharge l’application web, nous voulons lui montrer l’horaire des vols tel qu’il était la dernière fois qu’il l’a téléchargé avec une connexion.
Les bases
La première caractéristique d’une application web progressive est qu’elle doit fonctionner sur tous les appareils et doit s’améliorer sur les appareils et les navigateurs qui le permettent. Par conséquent, nous avons construit notre site Web en utilisant le HTML5 traditionnel et avec JavaScript qui simule la récupération de données à partir d’une API fictive. Dans toute l’application, nous utilisons des petits bouts de Knockout pour gérer nos liaisons Modèle-Vue-VueModèle (MVVM) – un cadre JavaScript léger qui nous permet de lier nos modèles JavaScript à nos vues HTML. Nous avons choisi d’utiliser Knockout parce qu’il est relativement simple à comprendre et qu’il n’encombre pas le code ; vous pouvez toutefois le remplacer par tout autre framework, comme React ou AngularJS.
Notre site Web suit les directives de conception matérielle de Google, un ensemble de principes qui guident la conception et l’interaction. Le material design sert non seulement de norme unifiée à travers les applications et les appareils, mais il donne également un sens au design. Nous avons utilisé le material design pour la vue des arrivées de Sky High afin de donner à notre application web progressive un aspect et une sensation d’application native.
Enfin, nous avons testé notre application pour nous assurer qu’elle est exempte de jank et que le défilement est doux comme de la soie. Il a été démontré qu’un rendu sans janking améliore l’engagement des utilisateurs. Visez un rendu de 60 images par seconde.
Pour cette démo, nous allons récupérer un fichier JSON statique, au lieu d’une véritable API. Ceci est simplement pour garder les choses simples. Dans le monde réel, vous interrogeriez une API ou utiliseriez des WebSockets.
index.html
<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sky-High Airport Arrivals</title> <link async rel="stylesheet" href="./css/style.css"> <link href="https://fonts.googleapis.com/css?family=Roboto:300,600,300italic,600italic" rel="stylesheet" type="text/css"></head><body> <header> <div class="content"> <h3>Arrivals</h3> </div> </header> <div class="container"> <div class="content"> <ul class="arrivals-list" data-bind="foreach: arrivals"> <li class="item"> <span class="title" data-bind="html: title"></span> <span class="status" data-bind="html: status"></span> <span class="time" data-bind="html: time"></span> </li> </ul> </div> </div> <script src="./js/build/vendor.min.js"></script> <script src="./js/build/script.min.js"></script></body></html>
Le fichier index.html
est relativement standard. Nous avons créé une liste HTML et lié notre propriété View Model arrivals
à celle-ci à l’aide de Knockout, via l’attribut data-bind="foreach: arrivals”
. Le View Model arrivals
est déclaré dans le fichier page.js
ci-dessous et exposé dans le module Page
. Sur notre page HTML, pour chaque élément du tableau arrivals
, nous avons lié les propriétés title
status
et time
à la vue HTML.
page.js
(var Page = (function() { // declare the view model used within the page function ViewModel() { var self = this; self.arrivals = ko.observableArray(); } // expose the view model through the Page module return { vm: new ViewModel(), hideOfflineWarning: function() { // enable the live data document.querySelector(".arrivals-list").classList.remove('loading') // remove the offline message document.getElementById("offline").remove(); // load the live data }, showOfflineWarning: function() { // disable the live data document.querySelector(".arrivals-list").classList.add('loading') // load html template informing the user they are offline var request = new XMLHttpRequest(); request.open('GET', './offline.html', true); request.onload = function() { if (request.status === 200) { // success // create offline element with HTML loaded from offline.html template var offlineMessageElement = document.createElement("div"); offlineMessageElement.setAttribute("id", "offline"); offlineMessageElement.innerHTML = request.responseText; document.getElementById("main").appendChild(offlineMessageElement); } else { // error retrieving file console.warn('Error retrieving offline.html'); } }; request.onerror = function() { // network errors console.error('Connection error'); }; request.send(); } }})();
Ce fichier page.js
expose le module Page
, qui contient notre ViewModel vm
et deux fonctions, hideOfflineWarning
et showOfflineWarning
. Le modèle de vue ViewModel
est un simple littéral JavaScript qui sera utilisé dans toute l’application. La propriété arrivals
sur le ViewModel est la observableArray
de Knockout, qui lie automatiquement notre HTML à un tableau JavaScript, ce qui nous permet de pousser et de faire sauter des éléments sur notre tableau en JavaScript et de mettre automatiquement à jour le HTML de la page.
Les fonctions hideOfflineWarning
et showOfflineWarning
permettent au reste de notre application d’appeler ces fonctions pour mettre à jour l’interface utilisateur de la page qui affiche si nous sommes connectés en ligne. Le showOfflineWarning
ajoute une classe de loading
à notre élément HTML arrivals-list
pour faire disparaître la liste, puis il récupère le fichier HTML offline.html
par XHR. En supposant que le fichier a été récupéré avec succès (response.status === 200
), nous l’ajoutons à notre HTML. Bien sûr, si nous n’utilisons pas de travailleurs de service et que l’utilisateur n’est pas connecté à Internet, alors il ne serait pas possible de récupérer offline.html
, et l’utilisateur verrait donc la page hors ligne du navigateur.
La logique métier à partir de laquelle nous récupérons les données de notre API et les lions à nos modèles de vue et à nos vues se trouve dans arrivals.js
et constitue une fonctionnalité MVVM standard utilisant Knockout. Dans le fichier arrivals.js
, nous initialisons simplement les services et les View Models que nous utiliserons tout au long de l’application, et nous exposons une fonction – Arrivals.loadData()
– qui récupère les données et les lie au modèle de vue.
Web App Manifest
Faisons en sorte que notre web app ressemble davantage à une app. Un fichier manifeste de web app est un simple fichier JSON qui suit la spécification du W3C. Grâce à lui, il est possible d’exécuter la web app en mode plein écran comme une application autonome, d’attribuer une icône qui s’affichera lorsque l’application sera installée sur l’appareil, et d’attribuer un thème et une couleur d’arrière-plan à l’app. En outre, Chrome sur Android suggère de manière proactive à l’utilisateur d’installer l’application Web, via une bannière d’installation de l’application Web. Pour afficher l’invite d’installation, votre web app doit :
- avoir un fichier manifeste de web app valide,
- être servie sur HTTPS,
- avoir un travailleur de service valide enregistré,
- avoir été visitée deux fois, avec au moins cinq minutes entre chaque visite.
manifeste.json
{ "short_name": "Arrivals", "name": "Arrivals at Sky High", "description": "Progressive web application demonstration", "icons": , "start_url": "./?utm_source=web_app_manifest", "display": "standalone", "orientation": "portrait", "theme_color": "#29BDBB", "background_color": "#29BDBB"}
Décomposons ce fichier manifeste :
-
short_name
est un nom lisible par l’homme pour l’application. Dans Chrome pour Android, c’est également le nom qui accompagne l’icône sur l’écran d’accueil. -
name
est également un nom lisible par l’homme pour l’application et définit la façon dont l’application sera répertoriée. -
description
fournit une description générale de l’application Web. -
icons
définit un tableau d’images de différentes tailles qui serviront de jeu d’icônes de l’application. Dans Chrome pour Android, l’icône sera utilisée sur l’écran de démarrage, sur l’écran d’accueil et dans le sélecteur de tâches. -
start_url
est l’URL de départ de l’application. -
display
définit le mode d’affichage par défaut de l’application web :fullscreen
standalone
minimal-ui
oubrowser
. -
orientation
définit l’orientation par défaut de l’application Web :portrait
oulandscape
. -
theme_color
est la couleur du thème par défaut de l’application. Sur Android, elle est également utilisée pour colorer la barre d’état. -
background_color
définit la couleur de fond de l’application web. Dans Chrome, elle définit également la couleur de fond de l’écran d’accueil. -
related_applications
n’est pas implémentée dans notre exemple mais est utilisée pour spécifier les alternatives d’applications natives dans les différents app stores.
Ajouter la référence manifest.json
à la balise index.html
du fichier head
:
<link rel="manifest" href="./manifest.json">
Une fois qu’un utilisateur a ajouté l’application web à son écran d’accueil, il pourra renouer avec votre application immédiatement depuis son appareil, sans avoir à ouvrir directement le navigateur. Vous pouvez voir comment cela est bien plus qu’un signet web.
Ajouter à l’écran d’accueil sur Chrome pour Android from Smashing Magazine on Vimeo.
Service Workers
L’un des aspects les plus excitants des applications web progressives est qu’elles peuvent fonctionner hors ligne. En utilisant les travailleurs de service, il est possible d’afficher les données qui ont été récupérées dans les sessions précédentes de l’app (en utilisant IndexedDB) ou, alternativement, d’afficher le shell de l’application et d’informer l’utilisateur qu’il n’est pas connecté à Internet (l’approche que nous avons adoptée dans cette démo). Une fois que l’utilisateur se reconnecte, nous pouvons alors récupérer les dernières données du serveur.
Tout cela est possible grâce aux travailleurs de service, qui sont des scripts événementiels (écrits en JavaScript) ayant accès aux événements à l’échelle du domaine, y compris les récupérations réseau. Avec eux, nous pouvons mettre en cache toutes les ressources statiques, ce qui pourrait réduire drastiquement les requêtes réseau et améliorer considérablement les performances, aussi.
Coquille d’application
La coquille d’application est le minimum de HTML, CSS et JavaScript requis pour alimenter une interface utilisateur. Une application mobile native inclut le shell d’application dans le cadre de son distribuable, alors que les sites web le demandent ordinairement sur le réseau. Les applications web progressives comblent cette lacune en plaçant les ressources et les actifs de l’application shell dans le cache du navigateur. Dans notre application Sky High, nous pouvons voir que notre coquille d’application est constituée de la barre d’en-tête supérieure, des polices de caractères et de tout CSS nécessaire pour les rendre de manière élégante.
Pour commencer avec les travailleurs de service, nous devons d’abord créer le fichier JavaScript de notre travailleur de service, sw.js
, placé dans le répertoire racine.
sw.js
// Use a cacheName for cache versioningvar cacheName = 'v1:static';// During the installation phase, you'll usually want to cache static assets.self.addEventListener('install', function(e) { // Once the service worker is installed, go ahead and fetch the resources to make this work offline. e.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll().then(function() { self.skipWaiting(); }); }) );});// when the browser fetches a URL…self.addEventListener('fetch', function(event) { // … either respond with the cached object or go ahead and fetch the actual URL event.respondWith( caches.match(event.request).then(function(response) { if (response) { // retrieve from cache return response; } // fetch as normal return fetch(event.request); }) );});
Regardons de plus près notre travailleur de service. Tout d’abord, nous définissons une variable cacheName
. Celle-ci est utilisée pour déterminer si des modifications ont été apportées à nos actifs mis en cache. Pour cet exemple, nous utiliserons un nom statique, ce qui signifie que nos actifs ne changeront pas ou ne nécessiteront pas de mise à jour.
self.addEventListener('install', function(e) { // declare which assets to cache}
L’événement install
se déclenche pendant la phase d’installation du prestataire de services et ne se déclenchera qu’une seule fois si le prestataire de services est déjà installé. Par conséquent, le rafraîchissement de la page ne déclenchera pas à nouveau la phase d’installation. Pendant la phase d’installation, nous pouvons déclarer quels actifs seront mis en cache. Dans notre exemple ci-dessus, nous mettons en cache un fichier CSS, deux fichiers JavaScript, notre fichier de polices, notre modèle HTML hors ligne et, bien sûr, la racine de l’application. self.skipWaiting()
force le travailleur de service en attente à devenir actif.
Jusqu’ici, nous avons déclaré notre travailleur de service, mais avant de le voir entrer en vigueur, nous devons le référencer dans notre JavaScript. Dans notre application, nous l’enregistrons dans main.js
// Register the service worker if available.if ('serviceWorker' in navigator) { navigator.serviceWorker.register('./sw.js').then(function(reg) { console.log('Successfully registered service worker', reg); }).catch(function(err) { console.warn('Error whilst registering service worker', err); });}window.addEventListener('online', function(e) { // Resync data with server. console.log("You are online"); Page.hideOfflineWarning(); Arrivals.loadData();}, false);window.addEventListener('offline', function(e) { // Queue up events for server. console.log("You are offline"); Page.showOfflineWarning();}, false);// Check if the user is connected.if (navigator.onLine) { Arrivals.loadData();} else { // Show offline message Page.showOfflineWarning();}// Set Knockout view model bindings.ko.applyBindings(Page.vm);
Nous avons également inclus deux écouteurs d’événements pour vérifier si l’état de la session a changé de online
offline
ou vice versa. Les gestionnaires d’événements appellent ensuite les différentes fonctions pour récupérer les données via Arrivals.loadData()
et pour activer ou désactiver le message hors ligne via Page.showOfflineWarning
et Page.hideOfflineWarning
, respectivement. Notre application vérifie également si l’utilisateur est actuellement en ligne, en utilisant navigator.onLine, et récupère les données ou affiche l’avertissement hors ligne en conséquence. Et dans la dernière ligne de main.js
, nous appliquons les liaisons Knockout à notre modèle de vue Page.vm
.
Si nous chargeons notre application pour la première fois (avec Chrome Developer Tools), nous ne verrons rien de nouveau. Cependant, en rechargeant, nous verrons qu’un certain nombre de ressources réseau ont été récupérées à partir du travailleur de service. Voici le shell de notre application.
Test hors ligne
Un utilisateur exécutant l’application sans connexion Internet (en supposant qu’il ait déjà été sur la page) verra simplement s’afficher le shell de l’application et l’avertissement hors ligne – une amélioration par rapport au t-rex rôdeur de Chrome. Une fois que l’utilisateur a établi une connexion réseau, nous désactivons l’avertissement et récupérons les dernières données.
Le Guardian adopte une approche particulièrement intéressante lorsque les utilisateurs hors ligne accèdent à son site Web, en proposant une grille de mots croisés :
Notifications push
Les notifications push permettent aux utilisateurs d’opter pour des mises à jour opportunes provenant d’applications auxquelles ils font confiance, ce qui les aide à se réengager avec ces applications. Les notifications push sur le web vous permettent de vous engager avec votre public même lorsque le navigateur est fermé.
L’API Push est prise en charge dans Chrome, Opera et le navigateur de Samsung et est en cours de développement dans Firefox et Microsoft Edge. Malheureusement, rien n’indique que la fonctionnalité sera mise en œuvre dans Safari.
Performance
L’une des victoires les plus faciles avec les travailleurs de service est que nous pouvons améliorer les performances avec peu ou pas d’effort. Si l’on compare notre site web à lui-même avant l’implémentation des travailleurs de service, avant nous récupérions plus de 200 Ko lors du chargement de la page ; cela est maintenant réduit à 13 Ko. Sur un réseau 3G ordinaire, la page aurait mis 3,5 secondes à se charger ; maintenant, elle prend 500 millisecondes.
Ces améliorations de performance sont drastiques parce que l’application elle-même est très petite et a des fonctionnalités limitées. Néanmoins, grâce à l’utilisation correcte de la mise en cache, il est possible d’améliorer considérablement les performances et les performances perçues, en particulier pour les utilisateurs dans les endroits à faible connectivité.
Lighthouse
L’équipe Chrome de Google a mis en place un outil pour tester les applications web progressives. Lighthouse fonctionne dans Node.js ou en tant que plugin Chrome et peut être trouvé sur GitHub, également.
Pour exécuter un test Lighthouse, votre site Web doit être disponible en ligne, ce qui signifie que vous ne pouvez pas tester sur localhost
.
Pour commencer, téléchargez le paquet npm :
npm install -g GoogleChrome/lighthouse
Une fois qu’il est installé, exécutez Chrome (à partir de la version 52) :
npm explore -g lighthouse -- npm run chromelighthouse https://incredibleweb.github.io/pwa-tutorial/
La sortie de l’exécution de Lighthouse sera visible dans la ligne de commande et classera votre site Web en fonction des fonctionnalités et propriétés de l’application Web progressive que vous avez implémentées – par exemple, si vous utilisez un fichier manifest.json
ou si votre page est disponible hors ligne.
Conclusion
Cet article n’est qu’une mise en bouche pour les applications web progressives. Nous pourrions faire beaucoup plus pour créer cette expérience de type app que les utilisateurs recherchent, que ce soit en prenant en charge les notifications push avec l’API Push, en rendant l’app réengageable ou en utilisant IndexedDB et la synchronisation en arrière-plan pour améliorer l’expérience hors ligne.
Support inter-navigateur
Ce sont encore les premiers jours pour les apps web progressives, et le support inter-navigateur est encore limité, en particulier dans Safari et Edge. Cependant, Microsoft soutient ouvertement les applications web progressives et devrait mettre en œuvre davantage de fonctionnalités d’ici la fin de l’année.
- Service workers et Cache API. Pris en charge dans Chrome, Firefox, Opera et le navigateur de Samsung. En développement dans Microsoft Edge, devrait être disponible d’ici la fin de 2016. En cours d’examen pour Safari.
- Ajouter à l’écran d’accueil. Pris en charge dans Chrome, Firefox, Opera, Android Browser et le navigateur de Samsung. Microsoft semble indiquer que les applications web progressives seront disponibles en tant que listes de magasins. Aucun plan pour Safari pour le moment.
- Push API. Majoritairement prise en charge dans Chrome, Firefox, Opera et le navigateur de Samsung. En développement dans Microsoft Edge. Pas de plans pour Safari pour le moment.
Si davantage de développeurs profitent des fonctionnalités offertes par les applications web progressives – qui sont relativement faciles à mettre en œuvre et fournissent des récompenses immédiates – alors les utilisateurs préféreront consommer ces applications web dans les navigateurs pris en charge, en espérant convaincre les autres fournisseurs de navigateurs de s’adapter.