À la découverte des architectures du front (3/4) Les Single Page Applications.

Introduction

L’objectif de cette suite d’articles (sites statiques, MPA, SPA et applications universelles) est de faire le point sur les différentes architectures front-end. Pour cela, nous analyserons leur fonctionnement, avantages et inconvénients, ainsi que les besoins qui les ont fait émerger au fil du temps.

Comprendre l’historique de ces architectures permet de prendre de meilleures décisions lors du développement d’une nouvelle application.

Histoire

Le pattern SPA a émergé progressivement avec l’arrivée de nouvelles technologies.

La première notable est AJAX en 2004, qui permet d’échanger des données avec les serveurs sans déclencher de rechargement complet de la page. Javascript, jusqu’alors principalement utilisé pour enrichir les pages de petites animations, commence à être utilisé pour des interactions de plus en plus complexes, comme des mises à jour dynamiques de l’interface.

Deux ans plus tard, jQuery arrive sur le marché, en contribuant à l’adoption rapide du pattern SPA de trois façons essentielles :

- Compatibilité multi navigateurs

- Simplification des requêtes AJAX

- API de manipulation du DOM complète

La magie jQuery opère pendant plusieurs années, jusqu’à ce que des limites se fassent sentir dans le développement d’applications devenues trop complexes à maintenir. En tant que bibliothèque, jQuery ne donne aucune indication sur la façon de structurer son code.

L’utilisation de JavaScript étant devenue massive, les acteurs du web redoublent d’efforts pour sortir des navigateurs encore plus performants. En 2008, c’est Google qui frappe fort en sortant Google Chrome, qui se distingue avec son moteur d’exécution léger et rapide : V8 (en analogie avec les moteurs de voitures de course). Il surpassera la concurrence pendant plusieurs années grâce à l’intégration de la technologie crankshaft en 2010. Ceci a eu pour effet de diminuer le temps d’affichage des pages dont la construction se fait en JavaScript côté client.

Cette capacité de calcul accrue a contribué à l'essor des SPAs. Pour faciliter leur développement, de grands frameworks front se succèdent : AngularJS et Backbone.js (2010), puis d’Ember (2011), et plus récemment React (2013), Vue (2014) ou Angular (2016).

Cinématique

  1. L’utilisateur demande la page à l’url “/page1”
  2. Le serveur renvoie toujours le index.html
  3. Le navigateur affiche le index.html (page blanche ou page de chargement)
  4. Le navigateur va télécharger les assets : JavaScript, CSS, images
  5. Le navigateur parse et exécute le JavaScript
  6. Le JS construit le HTML et rend l'application interactive
  7. Le JS fait des appels à l’API et complète le HTML
  8. La navigation se fait entièrement côté navigateur
  9. Le client fait directement des appels d’API pour récupérer ou mettre à jour les données supplémentaires

Description

Dans une SPA, l’ensemble des assets du site sont chargés lorsque l’utilisateur arrive sur la première page. Tous les templates du site sont pré-chargés, il suffit de récupérer uniquement la donnée qui va les alimenter pour l’affichage.

Contrairement aux MPAs, la navigation se déroule directement côté client. Cela est rendu possible en émulant une navigation conventionnelle grâce à des artifices techniques liés au navigateur, d’abord par l’utilisation des URLs hashbangs (#), puis grâce à l’apparition de l’API history avec HTML5.

Cette approche marque une rupture avec l’ancien mode de fonctionnement, pour lequel tout le HTML de la page était envoyé par le serveur.

Cas d’utilisation type

Les Single Page Applications permettent de répondre au besoin de détenir une application web riche en interactions, avec une bonne expérience utilisateur, mais dont le référencement n’est pas un point vital.

Elles sont souvent utilisées sur des tunnels de vente, des espaces clients ou des questionnaires, et puisent leurs données dans des APIs (REST, graphql, etc).

Le développement d'une SPA introduit de nouveaux concepts de programmation (approche composant, sécurité, JavaScript, gestion d’état, ...), ce qui pousse les développeurs front à être capables de s'adapter rapidement dans un écosystème en perpétuelle évolution.

Caractéristiques

Industrialisation du développement front-end : Des frameworks apparaissent et facilitent le besoin croissant d’interactivité tout en évitant de compromettre la maintenabilité et la testabilité du code. Cette complexité grandissante entraîne l’arrivée de nouveaux outils pour permettre l’industrialisation des développements front. Il n’est plus concevable aujourd’hui de construire une application web sans gestionnaires de paquets (npm, yarn), de linters (eslint, tslint) ou d’outils de test (jest, jasmine).

Les applications front ont leurs propres cycles de vie, et sont incluses dans les outils d’intégration et de déploiement continu (jenkins, CircleCI).

Découplage induit du front-end et du back-end : Une SPA ayant besoin d’une source de données externe, sa mise en place s’accompagne donc très souvent de la mise en place d’une API. Cette API va être l’occasion pour un SI de définir comment les données métier sont exposées et comment il pourrait les séparer de la logique d’affichage pour aboutir à une architecture qui sépare les responsabilités.

Par ailleurs, cette séparation des couches facilite également la réutilisation du back-end sur de multiples canaux (application mobile, IoT, …).

Expérience utilisateur : Les SPAs ne nécessitant pas de chargements de pages supplémentaires pendant la navigation, le changement de page peut donc être plus fluide que sur une architecture conventionnelle.

Limitations

SEO limité : l’application nécessitant un moteur JavaScript pour s'exécuter et générer du HTML, les robot d’indexation ont du mal à lire le contenu du site web. Néanmoins, les moteurs de recherche se sont améliorés dans leur capacité à indexer les SPAs, sans toutefois atteindre le niveau d’indexation d’une page dont le HTML est rendu côté serveur.

Pour en savoir plus sur le SEO et les SPAs, en voici un très bon article.

Temps de chargement initial de l’application : Le temps avant la première interaction (TTI) est plus long. Cela s’explique par le besoin de télécharger toute l’application front au démarrage, avant de pouvoir générer les premiers éléments de la page. S’ajoutent à cela les différents appels à l’API pour remplir le template.

À noter que des techniques telles que le code splitting et le lazy loading de code peuvent être mises en place pour diminuer le temps d’affichage, rendues possibles grâce à webpack.

Problèmes de navigation : Il peut persister certains bugs liés à l’émulation de la navigation, par exemple le scroll qui se maintient lorsqu’on navigue vers une nouvelle page, ou alors la réinitialisation des champs de formulaire des pages précédentes.

Conclusion

Les Single Page Applications contribuent à démocratiser le concept d’application web. En effet, il est maintenant possible d’avoir un site web avec une interface et des fonctionnalités similaires à une application desktop. Néanmoins, il peut s’agir d’une forme de détournement des concepts du web, et cela nécessite la mise en place de multiples solutions de contournement pour avoir un comportement similaire à du web natif. Pour pallier ces problèmes, et se rapprocher du comportement natif, l’idée émerge de prendre le meilleur des deux mondes entre SPA et MPA.

C’est ainsi qu’est arrivé le concept des applications universelles, qui se comportent comme une MPA pour le chargement initial, puis comme une SPA pour la suite de la navigation. Ce sera l’objet du quatrième article de la série, à venir très prochainement.