Rendu côté client ou côté serveur ?

Voir la vidéo

Dans cette vidéo, je vous propose de découvrir les différentes méthodes de rendus possibles pour un site/application web.

Terminologie

Avant de commencer un petit point sur la terminologie liée à toutes les problématiques de rendu Web.

  • SSR Server-Side Rendering, le rendu de l'HTML est fait côté serveur.
  • CSR (Client-Side Rendering), le rendu de la structure se fait côté navigateur en manipulant le DOM.
  • Hydratation, câblage des vues JavaScript sur la structure déjà rendu côté serveur.
  • Prerendering, on exécute le code côté client pour rendre la page et sauvegarder le rendu HTML static.
  • Dynamic Rendering, consiste à délivrer une version HTML static du site pour les moteurs de recherche.

Et voici quelques temps clé pour parler du chargement d'une page web

  • TTFB: Time to First Byte représente le temps entre le clic sur un lien et le premier bit que l'on reçoit.
  • FP: First Paint, représente le moment où le premier pixel devient visible à l'écran de l'utilisateur.
  • FCP: First Contentful Paint, indique le moment où le contenu demandé (article, produit) devient visible à l'écran.
  • TTI: Time To Interactive, indique le moment où la page devient totalement interactive (écouteurs d'évènements branchés...).

Objectif HTML

Pour qu'une page web soit visible par nos utilisateur il faut du code HTML mais ce code peut être générer de 2 manières :

  • Côté serveur, le code HTML complet est renvoyé directement lors de la requête HTTP.
  • Côté client, le code HTML est généré côté navigateur par le JavaScript qui va manipuler le DOM

Rendu côté serveur

Comme son nom l'indique, dans ce type de rendu, c'est le serveur qui est responsable de renvoyer le code HTML de la page au navigateur. La page est peut-être rendue de manière dynamique via un langage de programmation côté serveur (PHP, JavaScript, Ruby, Python...) ou via de simples fichiers HTML.

Avantages :

  • Chargement initial rapide
  • Meilleur référencement
  • Choix technologiques, on contrôle le contexte d'exécution et on peut donc choisir le langage à utiliser

Inconvénients :

  • Navigation consécutive plus lente (chaque navigation recharge toute la page)
  • Aucun élément n'est persisté entre les pages (lecteur vidéo / audio, tchat ou autre)
  • Charge serveur plus importante (car le serveur doit recharger tout le contenu de la page pour chaque requête).

Rendu côté client

Dans ce type de rendu le code va être généré côté client via du code JavaScript exécuté côté navigateur. Le serveur se contentera de renvoyer une structure HTML simple qui sera modifié dans un second temps.

Avantages :

  • Navigation plus fluide entre les pages
  • Pas de rechargement total de la page à la moindre interaction
  • Page principale en HTML static, donc facile à déployer

Inconvénients :

  • Chargement initial plus long, car il faut exécuter le JavaScript puis attendre les données.
  • Technologie imposée (JavaScript) et on ne contrôle pas le contexte d'exécution.
  • Difficile à référencer, certains moteurs de recherche peuvent indexer le JavaScript, mais pas dans la première phase.
  • Architecture séparée (API d'un côté et code client de l'autre) ajoute de la complexité.

Seulement 2 approches ?

Dans la réalité, il n'existe pas simplement que ces 2 approches et il est possible de mélanger les choses en additionnant les 2 types de rendus afin de maximiser l'expérience utilisateur. Malgré tout ces approches "hybrides" auront une base côté serveur ou côté client.

SSR avec amélioration progressive

L'objectif de cette approche est de continuer à faire notre rendu côté serveur et à rajouter une légère surcouche de JavaScript qui va dynamiser la page. Par exemple, lorsque l'on va cliquer sur un lien, plutôt que de laisser le navigateur charger la nouvelle page, le nouveau contenu va être chargé en JavaScript puis une partie du contenu va être injecté dans la page courante. Cela permet d'avoir une expérience de navigation plus fluide, mais aussi de conserver certains éléments persistants lors de la navigation afin contrebalancer un des inconvénients que l'on avait vu précédemment. Cette approche peut être adoptée grâce à des technologies comme Hotwire ou Unpoly.
Pour les micro-interactions, il est possible d'utiliser des outils comme AlpineJS qui vont permettre, en insérant des attributs HTML, de dynamiser la page.

<div x-data="{ open: false }">
    <button @click="open = true">Afficher le spoiler</button>

    <span x-show="open">
      Le héro il meurt à la fin mais en fait il n'est pas vraiment mort !
    </span>
</div>

La particularité de cette approche est que le serveur reste le principal responsable du rendu HTML et des interactions utilisateurs. Le code JavaScript qui sera écrit sera souvent lié à de la manipulation de DOM

SSR avec hydratation partielle

Dans cette approche, on va rendre la quasi-totalité de la structure HTML côté serveur, mais avec certains éléments qui seront rendus côté client via du JavaScript. On peut par exemple se baser sur l'API des Custom Elements pour créer des éléments qui vont être chargés essentiellement côté client :

<article>
    <h1>Titre de l'article</h1>
    <p>Contenu de l'article...</p>
    <hr/>
    <post-comments post-id="3"></post-comments>
</article>

Dans cette approche, c'est Le JavaScript qui se chargera du rendu HTML de ces éléments-là et on aura donc un mélange entre des éléments rendus côté serveur et des éléments rendus côté client ce qui peut être complexe à maintenir. On peut aussi cumuler cette approche avec l'approche précédente si nécessaire.

CSR avec rendu côté serveur

Le principal problème du rendu côté client et son absence de référencement et un rendu initial plus lent. Pour contrebalancer ce problème, on peut choisir de faire du rendu côté serveur pour le chargement de initiale en utilisant un moteur de rendu JavaScript (via NodeJS) afin de rendre une version HTML de la page demandée par l'utilisateur. C'est cette version statique que l'on délivrera lors de la première requête faite à notre serveur. Le JavaScript prendra ensuite le relais en hydratant la page (il va lui aussi rendre la structure de la page et brancher les différents événements au DOM rendu par le serveur). Le reste de la navigation se fera ensuite côté client.

Cela permet d'avoir un site qui est référençable vu que la structure HTML peut être généré côté serveur et permet d'avoir un chargement initial plus rapide pour l'utilisateur. En revanche, cela est plus complexe à mettre en place et on est en général plus limité en termes de technologie :

CSR avec Dynamic Rendering

L'objectif de l'affichage dynamique et de faire en sorte que notre site créé côté client puisse être référencé. Pour cela le type de rendu sera adapté en fonction de qui visite le site. Si le site est parcouru par un robot d'indexation de moteur de recherche, on lui délivrera une version HTML du site, alors qu'un visiteur classique continuera à recevoir la version côté client.

Pour faire le rendu HTML on utilisera un navigateur headless (utilisable en ligne de commande sans retour visuel) qui va charger le site au complet (en attendant l'exécution du JavaScript et les modifications du DOM) et sauvegarder le rendu HTML final. Cette structure HTML sera ensuite délivrée au moteur d'indexation lorsqu'ils essaient d'accéder à une page (le rendu sera aussi mis en cache pour répondre plus rapidement la prochaine fois).

C'est une approche qui est assez complexe à mettre en place, mais qui peut être intéressante en dernier recours pour rendre un site créé côté client indexable.

Publié
Technologies utilisées
Auteur :
Grafikart
Partager