Côté client vs côté serveur vs pré-rendu pour les applications Web

Publié: 2022-03-11

Il se passe quelque chose au sein de la communauté front-end récemment. Le rendu côté serveur gagne de plus en plus de terrain grâce à React et sa fonction intégrée d'hydratation côté serveur. Mais ce n'est pas la seule solution pour offrir une expérience rapide à l'utilisateur avec un score de temps au premier octet (TTFB) super rapide : le pré-rendu est également une très bonne stratégie. Quelle est la différence entre ces solutions et une application entièrement rendue par le client ?

Application rendue par le client

Depuis que des frameworks comme Angular, Ember.js et Backbone existent, les développeurs frontaux ont tendance à tout rendre côté client. Grâce à Google et à sa capacité à « lire » JavaScript, cela fonctionne plutôt bien, et il est même optimisé pour le référencement.

Avec une solution de rendu côté client, vous redirigez la requête vers un seul fichier HTML et le serveur la livrera sans aucun contenu (ou avec un écran de chargement) jusqu'à ce que vous récupériez tout le JavaScript et que vous laissiez le navigateur tout compiler avant de rendre le contenu.

Sous une bonne et fiable connexion Internet, c'est assez rapide et fonctionne bien. Mais cela peut être beaucoup mieux, et cela ne doit pas être difficile de le faire de cette façon. C'est ce que nous verrons dans les sections suivantes.

Rendu côté serveur (SSR)

Une solution SSR est quelque chose que nous faisions beaucoup il y a de nombreuses années, mais que nous avons tendance à oublier au profit d'une solution de rendu côté client.

Avec les anciennes solutions de rendu côté serveur, vous construisiez une page Web, avec PHP par exemple, le serveur compilait tout, incluait les données et livrait une page HTML entièrement remplie au client. C'était rapide et efficace.

Mais… à chaque fois que vous naviguiez vers une autre route, le serveur devait refaire le travail : récupérez le fichier PHP, compilez-le et livrez le HTML, avec tout le CSS et le JS retardant le chargement de la page à quelques centaines de ms ou même des secondes entières.

Et si vous pouviez charger la première page avec la solution SSR, puis utiliser un framework pour effectuer un routage dynamique avec AJAX, en récupérant uniquement les données nécessaires ?

C'est pourquoi SSR gagne de plus en plus de terrain au sein de la communauté car React a popularisé ce problème avec une solution facile à utiliser : la méthode RenderToString .

Ce nouveau type d'application Web s'appelle une application universelle ou une application isomorphe . Il existe encore une certaine controverse sur la signification exacte de ces termes et la relation entre eux, mais de nombreuses personnes les utilisent de manière interchangeable.

Quoi qu'il en soit, l'avantage de cette solution est de pouvoir développer une application côté serveur et côté client avec le même code et offrir une expérience très rapide à l'utilisateur avec des données personnalisées. L'inconvénient est que vous devez exécuter un serveur.

SSR est utilisé pour récupérer des données et pré-remplir une page avec un contenu personnalisé, en tirant parti de la connexion Internet fiable du serveur. C'est-à-dire que la propre connexion Internet du serveur est meilleure que celle d'un utilisateur avec lie-fi), il est donc capable de prérécupérer et de fusionner les données avant de les livrer à l'utilisateur.

Avec les données préremplies, l'utilisation d'une application SSR peut également résoudre un problème rencontré par les applications rendues par le client avec le partage social et le système OpenGraph. Par exemple, si vous n'avez qu'un seul fichier index.html à livrer au client, il n'aura qu'un seul type de métadonnées, très probablement les métadonnées de votre page d'accueil. Cela ne sera pas contextualisé lorsque vous souhaitez partager un itinéraire différent, donc aucun de vos itinéraires ne sera affiché sur d'autres sites avec leur propre contenu utilisateur (description et image d'aperçu) que les utilisateurs voudraient partager avec le monde.

Pré-rendu

Le serveur obligatoire pour une application universelle peut être dissuasif pour certains et peut être exagéré pour une petite application. C'est pourquoi le pré-rendu peut être une très bonne alternative.

J'ai découvert cette solution avec Preact et sa propre CLI qui vous permet de compiler toutes les routes présélectionnées afin que vous puissiez stocker un fichier HTML entièrement rempli sur un serveur statique . Cela vous permet d'offrir une expérience ultra-rapide à l'utilisateur, grâce à la fonction d'hydratation Preact/React, sans avoir besoin de Node.js.

Le problème est que, comme il ne s'agit pas de SSR, vous n'avez pas de données spécifiques à l'utilisateur à afficher à ce stade. Il s'agit simplement d'un fichier statique (et quelque peu générique) envoyé directement à la première requête, tel quel. Donc, si vous avez des données spécifiques à l'utilisateur, voici où vous pouvez intégrer un squelette magnifiquement conçu pour montrer à l'utilisateur que ses données arrivent, pour éviter une certaine frustration de sa part :

Utilisation d'un squelette de document dans le cadre d'un indicateur de chargement

Il y a un autre hic : pour que cette technique fonctionne, vous devez toujours avoir un proxy ou quelque chose pour rediriger l'utilisateur vers le bon fichier.

Pourquoi?

Avec une application d'une seule page, vous devez rediriger toutes les requêtes vers le fichier racine, puis le framework redirige l'utilisateur avec son système de routage intégré. Ainsi, le premier chargement de page est toujours le même fichier racine.

Pour qu'une solution de pré-rendu fonctionne, vous devez indiquer à votre proxy que certaines routes nécessitent des fichiers spécifiques et pas toujours le fichier racine index.html .

Par exemple, supposons que vous ayez quatre itinéraires ( / , /about , /jobs et blog ) et qu'ils aient tous des mises en page différentes. Vous avez besoin de quatre fichiers HTML différents pour livrer le squelette à l'utilisateur qui laissera ensuite React/Preact/etc. le réhydrater avec des données. Donc, si vous redirigez toutes ces routes vers le fichier racine index.html , la page aura une sensation désagréable et glitchy lors du chargement, par laquelle l'utilisateur verra le squelette de la mauvaise page jusqu'à ce qu'il finisse de se charger et remplace la mise en page. Par exemple, l'utilisateur peut voir un squelette de page d'accueil avec une seule colonne, alors qu'il a demandé une page différente avec une galerie de type Pinterest.

La solution consiste à indiquer à votre proxy que chacune de ces quatre routes nécessite un fichier spécifique :

  • https://my-website.com → Redirection vers le fichier racine index.html
  • https://my-website.com/about → Rediriger vers le fichier /about/index.html
  • https://my-website.com/jobs → Redirection vers le fichier /jobs/index.html
  • https://my-website.com/blog → Redirection vers le fichier /blog/index.html

C'est pourquoi cette solution peut être utile pour les petites applications - vous pouvez voir à quel point ce serait pénible si vous aviez quelques centaines de pages.

À proprement parler, il n'est pas obligatoire de le faire de cette façon - vous pouvez simplement utiliser directement un fichier statique. Par exemple, https://my-website.com/about/ fonctionnera sans aucune redirection car il recherchera automatiquement un index.html dans son répertoire. Mais vous avez besoin de ce proxy si vous avez des URL de paramètres - https://my-website.com/profile/guillaume devra rediriger la requête vers /profile/index.html avec sa propre mise en page, car profile/guillaume/index.html n'existe pas et déclenchera une erreur 404.

Un organigramme montrant comment un proxy fait la différence dans une solution de pré-rendu, comme décrit dans le paragraphe précédent


En bref, trois vues de base sont en jeu avec les stratégies de rendu décrites ci-dessus : un écran de chargement, un squelette et la page entière une fois qu'elle est finalement rendue.

Comparaison d'un écran de chargement, d'un squelette et d'une page entièrement rendue

Selon la stratégie, nous utilisons parfois ces trois vues, et parfois nous passons directement à une page entièrement rendue. Ce n'est que dans un cas d'utilisation que nous sommes obligés d'utiliser une approche différente :

Méthode Atterrissage (par exemple / ) Statique (par exemple /about ) Dynamique fixe (par exemple /news ) Dynamique paramétrée (par exemple /users/:user-id )
Rendu client Chargement → Complet Chargement → Complet Chargement → Squelette → Complet Chargement → Squelette → Complet
Pré-rendu Plein Plein Squelette → Complet HTTP 404 (page introuvable)
Pré-rendu avec proxy Plein Plein Squelette → Complet Squelette → Complet
RSS Plein Plein Plein Plein

Le rendu client uniquement n'est souvent pas suffisant

Les applications rendues par le client sont quelque chose que nous devrions éviter maintenant car nous pouvons faire mieux pour l'utilisateur. Et faire mieux, dans ce cas, est aussi simple que la solution de pré-rendu. C'est certainement une amélioration par rapport au rendu client uniquement et plus facile à mettre en œuvre qu'une application entièrement rendue côté serveur.

Une application SSR/universelle peut être vraiment puissante si vous avez une grande application avec beaucoup de pages différentes. Cela permet à votre contenu d'être ciblé et pertinent lorsque vous parlez à un crawler social. C'est également vrai pour les robots des moteurs de recherche, qui prennent désormais en compte les performances de votre site pour le classer.

Restez à l'écoute pour un tutoriel de suivi, où je vais parcourir la transformation d'un SPA en versions pré-rendues et SSR, et comparer leurs performances.

Connexe : Présentation des générateurs de sites statiques populaires