Pour concevoir votre application afin d'exploiter tout le potentiel de la technologie qui rend les PWA fiables, installables et performantes, il faut d'abord comprendre votre application et ses contraintes, puis choisir une architecture adaptée à ces deux aspects.
SPA et MPA
Aujourd'hui, il existe deux principaux modèles d'architecture dans le développement Web: les applications monopages (SPA) et les applications multipages (MPA).
Les applications monopages se caractérisent par le fait que le code JavaScript côté client contrôle la plupart ou la totalité du rendu HTML d'une page en fonction des données récupérées par l'application ou fournies à celle-ci. L'application remplace la navigation intégrée du navigateur par sa fonctionnalité de routage et de gestion des vues.
Les applications multipages envoient généralement du code HTML pré-rendu directement au navigateur, souvent amélioré avec du code JavaScript côté client une fois que le navigateur a terminé de charger le code HTML. Elles s'appuient sur les mécanismes de navigation intégrés du navigateur pour afficher les vues suivantes.
Les deux architectures peuvent être utilisées pour créer des PWA.
Chacune présente des avantages et des inconvénients. Choisir la bonne solution pour votre cas d'utilisation et votre contexte est essentielle pour offrir une expérience rapide et fiable à vos utilisateurs.
Applications monopages
- Mises à jour principalement atomiques dans la page.
- Dépendances côté client chargées au démarrage.
- Les chargements suivants sont rapides en raison de l'utilisation du cache.
- Coût de chargement initial élevé.
- Les performances dépendent du matériel de l'appareil et de la connexion réseau.
- Une complexité d'application supplémentaire est requise.
Les applications monopages sont adaptées à l'architecture si :
- L'interaction utilisateur est principalement axée sur les mises à jour atomiques de données interconnectées affichées sur la même page, par exemple un tableau de bord de données en temps réel ou une application de montage vidéo.
- Votre application comporte des dépendances d'initialisation côté client uniquement, par exemple un fournisseur d'authentification tiers dont le coût de démarrage est excessivement élevé.
- Les données requises pour le chargement d'une vue reposent sur un contexte spécifique côté client uniquement, par exemple pour afficher les commandes d'un appareil connecté.
- L'application est suffisamment petite et simple pour que sa taille et sa complexité n'aient pas d'impact sur les inconvénients listés ci-dessus.
Les SPA ne sont pas forcément un bon choix d'architecture dans les cas suivants :
- Les performances de chargement initial sont essentielles. Les SPA doivent généralement charger plus de code JavaScript pour déterminer ce qu'il faut charger et comment l'afficher. Le temps d'analyse et d'exécution de ce code JavaScript, combiné à la récupération du contenu, est plus lent que l'envoi du code HTML généré.
- Votre application s'exécute principalement sur des appareils à faible ou moyenne puissance. Étant donné que les SPA dépendent de JavaScript pour l'affichage, l'expérience utilisateur dépend beaucoup plus de la puissance de l'appareil spécifique que dans une MPA.
Étant donné que les applications monopages doivent remplacer la navigation intégrée du navigateur par leur routage, elles nécessitent un niveau de complexité minimal pour mettre à jour efficacement la vue actuelle, gérer les modifications de la navigation et nettoyer les vues précédentes qui seraient autrement gérées par le navigateur, ce qui les rend globalement plus difficiles à gérer et plus lourdes pour l'appareil de l'utilisateur.
Applications multipages
- La plupart des mises à jour sont sur une seule page.
- La vitesse de rendu initiale est essentielle.
- Les scripts côté client peuvent être une amélioration.
- Les vues secondaires nécessitent un autre appel au serveur.
- Le contexte n'est pas conservé d'une vue à l'autre.
- Nécessite un serveur ou un pré-rendu.
Les applications multipages sont un bon choix d'architecture dans les cas suivants:
- L'interaction utilisateur est principalement axée sur l'affichage d'une seule donnée avec des données contextuelles facultatives, par exemple une application d'actualités ou d'e-commerce.
- La vitesse de rendu initiale est essentielle, car envoyer du code HTML déjà rendu au navigateur est plus rapide que de l'assembler à partir d'une requête de données après avoir chargé, analysé et exécuté une alternative basée sur JavaScript.
- L'interactivité ou le contexte côté client peuvent être inclus en tant qu'amélioration après le chargement initial. Par exemple, vous pouvez superposer un profil à une page affichée ou ajouter des composants secondaires côté client dépendant du contexte.
Les MPA ne sont pas forcément un bon choix d'architecture dans les cas suivants :
- Re-télécharger, réanalyser et réexécuter votre code JavaScript ou CSS est extrêmement coûteux. Cet inconvénient est atténué dans les PWA avec des service workers.
- Le contexte côté client, comme la position de l'utilisateur, n'est pas transféré de manière transparente entre les vues, et la réobtention de ce contexte peut être coûteuse. Il doit être capturé et récupéré, ou ré-importé entre les vues.
En effet, les vues individuelles doivent être rendues dynamiquement par un serveur ou pré-rendues avant d'être accessibles, ce qui peut limiter l'hébergement ou ajouter de la complexité aux données.
Laquelle choisir ?
Malgré ces avantages et inconvénients, les deux architectures sont valides pour créer votre PWA. Vous pouvez même les combiner pour différentes parties de votre application, en fonction de ses besoins. Par exemple, vous pouvez faire en sorte que les fiches Play Store suivent une architecture MPA et que le parcours de paiement suive une architecture SPA.
Quelle que soit votre décision, l'étape suivante consiste à comprendre comment utiliser au mieux les service workers pour offrir la meilleure expérience possible.
La puissance du service worker
Le service worker est très puissant au-delà du routage de base et de la diffusion des réponses réseau et mises en cache. Nous pouvons créer des algorithmes complexes qui peuvent améliorer l'expérience et les performances des utilisateurs.
Service worker includes (SWI)
Les inclusions de service worker (SWI) sont un modèle émergent qui consiste à utiliser les service workers comme partie intégrante de l'architecture d'un site. Le SWI divise les éléments individuels, généralement une page HTML, en morceaux en fonction de leurs besoins de mise en cache, puis les assemble à nouveau dans le service worker pour améliorer la cohérence, les performances et la fiabilité, tout en réduisant la taille du cache.
Cette image est un exemple de page Web. Elle se compose de cinq sections différentes qui la divisent en :
- Disposition globale.
- En-tête global (barre sombre en haut de l'écran).
- Zone de contenu (lignes et image au milieu à gauche).
- Barre latérale (barre haute de couleur moyennement foncée au milieu à droite).
- Pied de page (barre noire en bas de l'écran)
Mise en page globale
La mise en page globale ne changera probablement pas souvent et n'a aucune dépendance. C'est un bon candidat pour la mise en cache préalable.
En-tête et pied de page
L'en-tête et le pied de page généraux contiennent des éléments tels que le menu supérieur et le pied de page du site, et présentent un défi particulier: si la page doit être mise en cache dans son ensemble, ces éléments peuvent changer entre les chargements de la page, en fonction de la date à laquelle la page a été mise en cache.
En les séparant et en les mettant en cache indépendamment du contenu, vous pouvez vous assurer que les utilisateurs obtiendront toujours la même version, quel que soit le moment où ils sont mis en cache. Comme elles sont rarement mises à jour, elles sont également adaptées au préchargement. Ils ont cependant une dépendance : les fichiers CSS et JavaScript du site.
CSS et JavaScript
Dans l'idéal, le code CSS et JavaScript du site doit être mis en cache avec un contenu obsolète, tout en revalidant la stratégie pour permettre les mises à jour incrémentielles sans avoir à mettre à jour le service worker, comme c'est le cas avec les éléments mis en cache. Toutefois, elles doivent également être conservées à une version minimale chaque fois que le service worker est mis à jour avec un nouvel en-tête ou pied de page global. Par conséquent, leur cache doit également être mis à jour avec la dernière version des composants lors de l'installation du service worker.
Zone de contenu
Vient ensuite la zone de contenu. Selon la fréquence des mises à jour, la stratégie "Réseau d'abord" ou "Obsolète lors de la validation" est une bonne stratégie. Les images doivent être mises en cache avec une stratégie de mise en cache prioritaire, comme indiqué dans la section Mise en cache.
Barre latérale
Enfin, en supposant que le contenu de la barre latérale contient du contenu secondaire tel que des tags et des éléments associés, il n'est pas assez essentiel pour être extrait du réseau. Une stratégie "obsolète pendant la validation" fonctionne pour cela.
Maintenant, après avoir parcouru tout cela, vous pensez peut-être que vous ne pouvez effectuer ce type de mise en cache par section que pour les applications monopages. Toutefois, en adoptant des modèles inspirés des inclusions côté client ou des inclusions côté serveur dans votre service worker, avec certaines fonctionnalités avancées de service worker, vous pouvez le faire pour l'une ou l'autre architecture.
Essayez par vous-même
Vous pouvez essayer les inclusions de service worker avec le prochain atelier de programmation :
Réponses en streaming
La page précédente peut être créée à l'aide du modèle d'enveloppe d'application dans le monde des SPA, où l'enveloppe d'application est mise en cache, puis diffusée, et que le contenu est chargé côté client. Avec l'introduction et la large disponibilité de l'API Streams, l'enveloppe d'application et le contenu peuvent être combinés dans le service worker et diffusés en streaming vers le navigateur. Vous bénéficiez ainsi de la flexibilité de mise en cache de l'enveloppe d'application avec la vitesse des MPA.
Elle procède ainsi pour les raisons suivantes:
- Les flux peuvent être créés de manière asynchrone, ce qui permet à différents éléments d'un flux de provenir d'autres sources.
- Le demandeur d'un flux peut commencer à travailler sur la réponse dès que le premier bloc de données est disponible, au lieu d'attendre que l'élément entier soit terminé.
- Les analyseurs optimisés pour le streaming, y compris le navigateur, peuvent afficher progressivement le contenu du flux avant qu'il ne soit terminé, ce qui accélère les performances perçues de la réponse.
Grâce à ces trois propriétés des flux, les architectures basées sur les flux ont généralement de meilleures performances perçues que les autres.
L'API Streams est complexe et de bas niveau, ce qui peut s'avérer difficile. Heureusement, un module Workbox peut vous aider à configurer les réponses en streaming pour vos services workers.
Domaines, origines et champ d'application de la PWA
Les workers Web, y compris les service workers, le stockage, et même la fenêtre d'une PWA installée, sont tous régis par l'un des mécanismes de sécurité les plus critiques du Web : la règle de même origine. Dans la même origine, des autorisations sont accordées, des données peuvent être partagées et le service worker peut communiquer avec différents clients. En dehors de la même origine, les autorisations ne sont pas automatiquement accordées, et les données sont isolées et inaccessibles entre différentes origines.
Règle de même origine
Deux URL sont définies comme ayant la même origine exacte si le protocole, le port et l'hôte sont identiques.
Par exemple, https://squoosh.app
et https://squoosh.app/v2
ont la même origine, mais http://squoosh.app
, https://squoosh.com
, https://app.squoosh.app
et https://squoosh.app:8080
ont des origines différentes. Pour en savoir plus et obtenir des exemples, consultez la documentation de référence MDN sur la règle de même origine.
Changer de sous-domaine n'est pas le seul moyen de changer un hôte. Chaque hôte se compose d'un domaine de premier niveau (TLD), d'un domaine de niveau secondaire (SLD) et de zéro, un ou plusieurs libellés (parfois appelés sous-domaines). Ceux-ci sont séparés par des points entre eux et lus de droite à gauche dans une URL. Si vous modifiez l'un de ces éléments, un autre hôte est sélectionné.
Dans le module de gestion des fenêtres, nous avons déjà vu à quoi ressemble le navigateur intégré à l'application lorsqu'un utilisateur accède à une autre origine à partir d'une PWA installée.
Ce navigateur intégré à l'application s'affiche même si les sites Web ont le même TLD et le même SLD, mais avec des libellés différents, car ils sont alors considérés comme des origines différentes.
L'un des aspects clés d'une origine dans un contexte de navigation Web est le fonctionnement du stockage et des autorisations. Une origine partage de nombreuses fonctionnalités entre tous les contenus et PWA qu'elle contient, y compris :
- Quota de stockage et données (IndexedDB, cookies, stockage Web, stockage cache).
- Inscriptions de service workers.
- Autorisations accordées ou refusées (par exemple, Web Push, géolocalisation, capteurs).
- Enregistrements Web push.
Lorsque vous passez d'une origine à une autre, tous les accès précédents sont révoqués. Les autorisations doivent donc être accordées à nouveau, et votre PWA ne peut pas accéder à toutes les données enregistrées dans l'espace de stockage.