Comment optimiser les applications Web progressives : aller au-delà des bases

Publié: 2022-03-10
Résumé rapide ↬ Il a été prouvé que les applications Web progressives augmentent l'engagement des utilisateurs et réduisent efficacement les coûts. Construire une PWA moderne nécessite plus que la configuration de base pour répondre aux attentes de l'utilisateur. Par conséquent, examinons de première main l'ajout de caractéristiques contemporaines aux PWA, du fonctionnement hors ligne aux demandes d'autorisation conviviales.

Les applications Web progressives (PWA) gagnent toujours en popularité en 2020. Cela n'est pas une surprise, compte tenu des avantages des taux de conversion plus élevés, de l'engagement des clients, de la vitesse de chargement des pages réduite et de la réduction des coûts de développement et des frais généraux.

Nous pouvons voir des entreprises respectées connaître également du succès avec leurs PWA, telles que Twitter, Uber, Tinder, Pinterest et Forbes. Et ils se vantent tous des avantages énormes de la mise en œuvre des applications progressives.

La bonne nouvelle est que le développement d'une PWA n'est pas quelque chose que seules les entreprises à gros budget peuvent se permettre. Ces applications servent également les petites et moyennes entreprises et ne sont pas si compliquées à créer.

Vous pouvez trouver un guide complet du débutant sur les applications Web progressives sur Smashing Magazine qui se concentre sur la construction du noyau des PWA.

Cependant, allons plus loin et apprenons à déployer des qualités modernes sur les PWA, telles que les fonctionnalités hors ligne, l'optimisation basée sur le réseau, l'expérience utilisateur multi-appareils, les capacités de référencement et les notifications et demandes non intrusives. Vous trouverez également des exemples de code ou des références à des guides plus spécifiques afin que vous puissiez mettre en œuvre ces conseils sur votre PWA.

Un aperçu rapide des applications Web progressives (PWA)

Ne sautons pas les bases et passons rapidement au cœur des PWA.

Qu'est-ce qu'une PWA ?

"Les applications Web progressives (PWA) sont conçues et améliorées avec des API modernes pour offrir des capacités, une fiabilité et une installabilité améliorées tout en atteignant n'importe qui, n'importe où, sur n'importe quel appareil avec une seule base de code."

— Les développeurs de Google

En d'autres termes, les PWA sont des sites Web que les utilisateurs peuvent utiliser comme applications autonomes. Elles sont différentes des applications natives principalement parce que les PWA ne nécessitent pas d'installation et peuvent être utilisées avec divers appareils — les applications natives sont principalement conçues pour les appareils mobiles.

Comment fonctionnent les PWA ?

Le cœur d'une PWA se compose de trois composants : un manifeste d'application Web, des service workers et un shell d'application. Vous pouvez trouver des instructions détaillées pour les construire dans le guide du débutant mentionné ci-dessus.

Voici ce que font ces composants.

Manifeste d'application Web

Le manifeste d'application Web est au cœur de l'exécution d'un site Web en tant qu'application autonome en mode plein écran. Vous pouvez définir l'apparence de la PWA, l'optimiser pour différents appareils et attribuer une icône qui s'affiche après l'installation de l'application.

Travailleurs des services

Les agents de service permettent l'utilisation hors ligne de la PWA en récupérant les données mises en cache ou en informant l'utilisateur de l'absence de connexion Internet. Les agents de service récupèrent également les dernières données une fois la connexion au serveur rétablie.

Architecture de shell d'application

Le shell de l'application est ce que les utilisateurs voient lorsqu'ils accèdent à une PWA. C'est le minimum de HTML, CSS et JavaScript requis pour alimenter l'interface utilisateur. Lors du développement d'une PWA, vous pouvez mettre en cache les ressources et les actifs du shell de l'application dans le navigateur.

Plus après saut! Continuez à lire ci-dessous ↓

Déployer des fonctionnalités modernes sur votre PWA

En plus des fonctionnalités de base, les PWA modernes adoptent des caractéristiques supplémentaires qui poussent davantage leurs utilisateurs vers une expérience utilisateur plus extraordinaire.

Examinons quelques caractéristiques modernes spécifiques d'une PWA et apprenons comment les ajouter à votre PWA. Les qualités suivantes sont considérées comme d'excellents ajouts à la PWA de base par les développeurs de Google.

L'application fonctionne hors ligne comme en ligne

Lors de la création de votre PWA, vous pouvez également développer une page hors ligne personnalisée dans le cadre du noyau. Cependant, il est beaucoup plus convivial si votre PWA continue de fonctionner même sans connexion Internet - jusqu'à un certain point où la connexion devient nécessaire. Sinon, l'expérience utilisateur pourrait être aussi frustrante que l'épreuve d'Ankita Masand avec la commande d'un gâteau comme elle le décrit dans son article sur les points faibles des PWA.

Vous pouvez obtenir une expérience utilisateur plus significative en utilisant le contenu mis en cache, la synchronisation en arrière-plan et les écrans squelettes. Regardons chacun.

Contenu mis en cache avec IndexedDB

IndexedDB est un système de stockage NoSQL intégré au navigateur que vous pouvez utiliser pour mettre en cache et récupérer les données requises pour que votre PWA fonctionne hors ligne.

Cependant, tous les navigateurs ne prennent pas en charge IndexedDB , donc la première chose à faire est de vérifier si le navigateur de l'utilisateur le prend en charge.

 if (!('indexedDB' in window)) { console.log('This browser doesn\'t support IndexedDB'); return; }

Après cela, vous pouvez créer du contenu mis en cache avec l'API IndexedDB. Voici un exemple des développeurs Google d'ouverture d'une base de données, d'ajout d'un magasin d'objets et d'ajout d'un article à ce magasin.

 var db; var openRequest = indexedDB.open('test_db', 1); openRequest.onupgradeneeded = function(e) { var db = e.target.result; console.log('running onupgradeneeded'); if (!db.objectStoreNames.contains('store')) { var storeOS = db.createObjectStore('store', {keyPath: 'name'}); } }; openRequest.onsuccess = function(e) { console.log('running onsuccess'); db = e.target.result; addItem(); }; openRequest.onerror = function(e) { console.log('onerror!'); console.dir(e); }; function addItem() { var transaction = db.transaction(['store'], 'readwrite'); var store = transaction.objectStore('store'); var item = { name: 'banana', price: '$2.99', description: 'It is a purple banana!', created: new Date().getTime() }; var request = store.add(item); request.onerror = function(e) { console.log('Error', e.target.error.name); }; request.onsuccess = function(e) { console.log('Woot! Did it'); }; }

Synchronisation en arrière-plan

Si votre PWA synchronise les données en arrière-plan, l'utilisateur peut prendre des mesures hors ligne, qui sont ensuite exécutées lorsque la connexion Internet est rétablie. Un exemple simple est une application de messagerie. Un utilisateur peut envoyer un message lorsqu'il est hors ligne sans avoir à attendre qu'il soit envoyé - la synchronisation en arrière-plan envoie automatiquement le message lorsque la connexion est rétablie.

Voici un exemple de développement d'une fonctionnalité de synchronisation en arrière-plan par Jake Archibald.

 // Register your service worker: navigator.serviceWorker.register('/sw.js'); // Then later, request a one-off sync: navigator.serviceWorker.ready.then(function(swRegistration) { return swRegistration.sync.register('myFirstSync'); });

Ensuite, écoutez l'événement dans /sw.js :

 self.addEventListener('sync', function(event) { if (event.tag == 'myFirstSync') { event.waitUntil(doSomeStuff()); } });

Écrans squelettes

L'un des principaux avantages de l'utilisation d'écrans squelettes est que les utilisateurs perçoivent l'application en train de fonctionner plutôt que de rester inactive. Tant que l'utilisateur n'a pas de connexion, l'écran squelette dessine l'interface sans contenu - qui se remplit ensuite une fois la connexion rétablie.

Code My UI propose d'excellents extraits de code que vous pouvez utiliser pour créer un squelette d'écran pour votre PWA.

Exemples d'écran squelette sur Code My UI
Exemples d'écran squelette sur Code My UI. ( Grand aperçu )

Optimisation basée sur l'utilisation du réseau

L'un des principaux avantages d'une PWA est qu'elle offre une expérience plus rapide aux utilisateurs. Vous pouvez optimiser davantage la vitesse de chargement en faisant en sorte que la PWA utilise la mise en réseau cache d'abord, en hiérarchisant les ressources et en utilisant un chargement adaptatif basé sur la qualité du réseau.

Voyons comment vous pouvez les développer pour votre PWA.

Cache d'abord, puis réseau

L'utilisation du contenu mis en cache permet d'abord à votre PWA de fonctionner hors ligne et ouvre la voie aux utilisateurs pour accéder au contenu même dans les zones à faible couverture réseau. Vous pouvez le faire en créant un agent de service pour mettre en cache le contenu, puis en le récupérant.

Voici un exemple de Jeff Posnick sur la mise en cache de HTML statique à l'aide de service workers.

 self.addEventListener('fetch', event => { if (event.request.mode === 'navigate') { // See /web/fundamentals/getting-started/primers/async-functions // for an async/await primer. event.respondWith(async function() { // Optional: Normalize the incoming URL by removing query parameters. // Instead of https://example.com/page?key=value, // use https://example.com/page when reading and writing to the cache. // For static HTML documents, it's unlikely your query parameters will // affect the HTML returned. But if you do use query parameters that // uniquely determine your HTML, modify this code to retain them. const normalizedUrl = new URL(event.request.url); normalizedUrl.search = ''; // Create promises for both the network response, // and a copy of the response that can be used in the cache. const fetchResponseP = fetch(normalizedUrl); const fetchResponseCloneP = fetchResponseP.then(r => r.clone()); // event.waitUntil() ensures that the service worker is kept alive // long enough to complete the cache update. event.waitUntil(async function() { const cache = await caches.open('my-cache-name'); await cache.put(normalizedUrl, await fetchResponseCloneP); }()); // Prefer the cached response, falling back to the fetch response. return (await caches.match(normalizedUrl)) || fetchResponseP; }()); } });

Prioriser les ressources

Par défaut, les PWA ont de meilleures performances que les applications natives similaires en raison de leur nature légère. De plus, puisque les PWA utilisent le cache du navigateur, il est possible d'indiquer quelles ressources sont prioritaires et doivent être rendues avant même qu'elles ne soient utilisées. Cela fonctionne principalement avec des éléments statiques car le contenu dynamique doit être mis à jour avant d'être récupéré.

Vous pouvez spécifier la priorité des éléments en utilisant la chaîne <link> dans le HTML. Vous pouvez également spécifier des fichiers de serveur tiers en utilisant rel=”preconnect” et rel=”dns-prefetch.”

Maximiliano Firtman en donne un exemple simple en donnant la priorité aux polices Web dans le moteur du navigateur :

 <link rel=”preload” as=”font” href=”font.woff” crossorigin>

Implémentation du chargement adaptatif

Les vitesses Internet du WiFi et de la 4G ne sont pas accessibles partout, et les utilisateurs accèdent toujours à Internet avec des connexions 2G et 3G. Étant donné que vous souhaitez que votre PWA soit accessible au plus grand nombre de personnes possible, vous souhaiterez peut-être l'optimiser pour qu'elle fonctionne également à des vitesses Internet inférieures.

Vous pouvez y parvenir en implémentant le chargement adaptatif, qui charge les éléments PWA en fonction du type de connexion dont dispose l'utilisateur.

Illustration de chargement adaptatif par Google.
Illustration de chargement adaptatif par Google. ( Grand aperçu )

Le moyen le plus simple consiste à utiliser l'outil Workbox de Google, qui comprend de nombreux plugins prêts à l'emploi pour les stratégies de mise en cache.

Supposons que vous souhaitiez définir une stratégie de mise en cache personnalisée. Voici comment vous pouvez le faire à titre d'exemple de Demian Renzulli et Jeff Posnick :

 const adaptiveLoadingPlugin = { requestWillFetch: async ({request}) => { const urlParts = request.url.split('/'); let imageQuality; switch ( navigator && navigator.connection ? navigator.connection.effectiveType : '' ) { //... case '3g': imageQuality = 'q_30'; break; //... } const newUrl = urlParts .splice(urlParts.length - 1, 0, imageQuality) .join('/') .replace('.jpg', '.png'); const newRequest = new Request(newUrl.href, {headers: request.headers}); return newRequest; }, };

Ensuite, passez le plugin à une stratégie cacheFirst contenant une expression régulière pour faire correspondre les URL d'image (par exemple /img/ ) :

 workbox.routing.registerRoute( new RegExp('/img/'), workbox.strategies.cacheFirst({ cacheName: 'images', plugins: [ adaptiveLoadingPlugin, workbox.expiration.Plugin({ maxEntries: 50, purgeOnQuotaError: true, }), ], }), );

Excellente expérience utilisateur sur toutes les plateformes

Un excellent PWA fonctionne de manière transparente sur les navigateurs, les mobiles et les tablettes. Bien que l'utilisation d'un appareil Android soit le moyen le plus populaire (avec une part de marché de 38,9 %) d'accéder à Internet, l'optimisation de votre application pour toutes les plates-formes fait partie du développement des fonctions de base des PWA.

Vous pouvez prendre d'autres mesures pour augmenter la convivialité et offrir une excellente expérience utilisateur, comme réduire les sautes d'humeur lors du chargement de votre PWA et vous assurer que votre PWA fonctionne avec n'importe quelle méthode de saisie.

Voici comment vous pouvez aborder chacun de ces aspects.

Réduire le chargement de contenu « instable »

Même avec Internet haute vitesse, le contenu du site peut changer pendant le chargement car les éléments du site se chargent dans l'ordre. Cet effet est encore pire avec des vitesses de connexion plus lentes et nuit gravement à l'expérience de l'utilisateur.

Les éléments les plus courants provoquant le décalage du contenu lors du chargement sont les images, car elles sont généralement plus grandes et ne sont pas prioritaires lors du chargement du contenu. Vous pouvez résoudre ce problème avec le "chargement différé" en utilisant des images d'espace réservé plus petites que vous pouvez hiérarchiser après le rendu de la structure HTML.

Voici un exemple des développeurs de Mozilla sur la façon dont vous pouvez ajouter une image légère chargée en premier avant l'image réelle en JavaScript :

 <img src='data/img/placeholder.png' data-src='data/img/SLUG.jpg' alt='NAME'>

Le fichier app.js traite les attributs data-src comme suit :

 let imagesToLoad = document.querySelectorAll('img[data-src]'); const loadImages = (image) => { image.setAttribute('src', image.getAttribute('data-src')); image.onload = () => { image.removeAttribute('data-src'); }; };

Et puis créez une boucle :

 imagesToLoad.forEach((img) => { loadImages(img); });

Vous pouvez également consulter un guide complet sur Smashing Magazine sur la réduction du saut de contenu avec d'autres éléments.

PWA fonctionne avec n'importe quelle méthode d'entrée

Nous avons expliqué comment les PWA devraient fonctionner avec une variété d'appareils différents. Pour aller plus loin, vous devez également tenir compte des autres méthodes de saisie que les utilisateurs peuvent utiliser sur ces appareils, telles que le toucher, la souris et le stylet.

L'ajout de l'API Pointer Events à votre PWA résout principalement cette question. Voici comment vous pouvez l'aborder selon les développeurs de Google.

Vérifiez d'abord si le navigateur prend en charge les événements de pointeur :

 if (window.PointerEvent) { // Yay, we can use pointer events! } else { // Back to mouse and touch events, I guess. }

Ensuite, vous pouvez définir les actions que différentes méthodes de saisie peuvent effectuer :

 switch(ev.pointerType) { case 'mouse': // Do nothing. break; case 'touch': // Allow drag gesture. break; case 'pen': // Also allow drag gesture. break; default: // Getting an empty string means the browser doesn't know // what device type it is. Let's assume mouse and do nothing. break; }

Étant donné que la plupart des navigateurs disposent déjà de fonctionnalités tactiles, vous n'aurez rien d'autre à ajouter.

Découvrable par la recherche

L'un des principaux avantages des PWA par rapport à une application native est que la PWA est un site Web par nature et que les moteurs de recherche peuvent les indexer. Cela vous permet de déployer des stratégies de référencement pour rendre votre contenu PWA plus visible.

Vous pouvez commencer par vous assurer que chaque URL de votre PWA a un titre descriptif et une méta description uniques, qui constituent la base de toute activité d'optimisation SEO.

Examinons quelques autres étapes que vous pouvez suivre pour rendre votre PWA consultable.

Analysez la trouvabilité de votre PWA

Google dispose d'un excellent outil dans sa console de recherche qui analyse votre site (PWA) et rapporte les résultats. Vous pouvez l'utiliser pour exécuter une analyse de base de votre site et découvrir les points faibles que vous pouvez ensuite commencer à corriger.

Vous pouvez également utiliser Lighthouse dans le navigateur Chrome pour exécuter un audit SEO.

Tout d'abord, accédez à l'URL cible. Appuyez ensuite sur Control+Shift+J (ou Command+Option+J sur Mac) qui ouvre le menu des outils du développeur. Choisissez l'onglet Phare, cochez la case de la catégorie SEO et générez le rapport.

Capture d'écran SEO de la catégorie des outils de développement Lighthouse du navigateur Google Chrome.
Capture d'écran SEO de la catégorie des outils de développement Lighthouse du navigateur Google Chrome. ( Grand aperçu )

Utiliser des données structurées

Le moteur de recherche de Google utilise des données structurées pour comprendre l'objectif du contenu de votre page Web.

Les données structurées sont un format standardisé pour fournir des informations sur une page et classer le contenu de la page ; par exemple, sur une page de recette, quels sont les ingrédients, le temps et la température de cuisson, les calories, etc.
- Google

Avant de commencer à coder, Google a également dressé une liste utile d'erreurs de données structurées courantes et de directives pertinentes pour les corriger. L'étude de ce matériel devrait vous donner une bonne base de ce qu'il faut éviter.

Frederick O'Brien a écrit un excellent guide sur Smashing Magazine, Baking Structured Data Into The Design Process , qui décrit comment créer des données structurées dès le départ.

Notifications et demandes d'autorisation conviviales

Enfin et surtout, vous pouvez améliorer l'expérience utilisateur en optimisant les notifications et les demandes d'autorisation, afin qu'elles servent vos utilisateurs - au lieu d'être simplement déroutantes et ennuyeuses.

Bien que vous puissiez généralement compter sur le bon sens, il existe des conseils pratiques que vous pouvez également mettre en œuvre, tels que la création de notifications push non intrusives et la possibilité pour l'utilisateur de se désabonner des messages.

Demandes d'autorisation subtiles pour la communication

Il existe deux façons modernes d'automatiser la communication entre un site Web et un utilisateur : les chatbots et les notifications.

Dans un contexte PWA, le principal avantage d'un chatbot est qu'il ne nécessite pas l'autorisation de l'utilisateur pour interagir avec l'utilisateur. Cependant, selon l'application de chatbot que vous utilisez, l'utilisateur peut manquer le message subtil. Les notifications, en revanche, nécessitent l'autorisation de l'utilisateur mais sont beaucoup plus visibles.

Puisque vous pouvez ajouter un chatbot en tant qu'application tierce distincte, concentrons-nous sur la création d'une notification push conviviale. Au cas où vous auriez besoin d'un guide sur la façon de créer une notification push en premier lieu, en voici un excellent par Indrek Lasn.

Le moyen le plus simple de créer une demande d'autorisation non intrusive consiste à utiliser une double demande. Cela signifie que vous incluez une interaction personnalisée sur votre site en plus de celle par défaut du système d'exploitation de l'utilisateur.

Matt Gaunt offre des illustrations parfaites pour cet effet avec les images suivantes.

Voici la demande d'autorisation de notification par défaut qui ne fournit aucun contexte :

Mauvais exemple de demande d'autorisation UX
Mauvais exemple de demande d'autorisation UX par Permission UX. ( Grand aperçu )

Et voici l'interaction personnalisée ajoutée avant l'autorisation de notification par défaut décrite ci-dessus :

Bon exemple de demande d'autorisation UX
Bon exemple de demande d'autorisation UX par Permission UX. ( Grand aperçu )

En ajoutant une alerte personnalisée avant celle par défaut du système d'exploitation, vous pouvez décrire plus clairement le but de la notification à l'utilisateur. Cela augmente les chances que l'utilisateur accepte les notifications de votre site.

Permettre à l'utilisateur de se désabonner des notifications

Pour un utilisateur, désactiver les notifications push d'un site est assez ennuyeux quel que soit l'appareil qu'il utilise. Par conséquent, donner à l'utilisateur la possibilité de se désabonner des messages contribue grandement à l'expérience utilisateur.

Voici un exemple de Matt Gaunt sur la façon d'implémenter une fonction de désabonnement dans votre code et votre interface utilisateur :

Tout d'abord, définissez l'écouteur de clic du pushButton :

 pushButton.addEventListener('click', function() { pushButton.disabled = true; if (isSubscribed) { unsubscribeUser(); } else { subscribeUser(); } });

Ensuite, ajoutez une nouvelle fonction :

 function unsubscribeUser() { swRegistration.pushManager.getSubscription() .then(function(subscription) { if (subscription) { // TODO: Tell application server to delete subscription return subscription.unsubscribe(); } }) .catch(function(error) { console.log('Error unsubscribing', error); }) .then(function() { updateSubscriptionOnServer(null); console.log('User is unsubscribed.'); isSubscribed = false; updateBtn(); }); }

Voici à quoi cela ressemble dans la console après avoir implémenté avec succès le bouton d'abonnement pour désactiver les notifications si l'utilisateur le souhaite.

Console.log exemple d'une fonction d'activation/désactivation réussie des notifications
Exemple Console.log d'une fonction d'activation/désactivation réussie des notifications par Matt Gaunt. ( Grand aperçu )

Conclusion

Les PWA peuvent être très puissants pour augmenter le trafic de votre site et étendre l'expérience utilisateur. Pour optimiser davantage votre PWA, vous pouvez utiliser ces solutions modernes décrites dans cet article pour améliorer les performances et les fonctionnalités.

Vous n'avez pas non plus besoin de tout mettre en œuvre en même temps. N'hésitez pas à sélectionner les options les plus pertinentes, car chacune de ces suggestions vous aide à faire avancer votre PWA.

Autres ressources

  • Formation aux applications Web progressives par Google
  • Applications Web progressives par web.dev
  • Applications Web progressives (PWA) de Mozilla