Next.js

Voir la vidéo

Dans cette vidéo, je vous propose de découvrir ensemble ce qu'est Next.js et de voir les différents types de rendus possibles.

Un framework pour React

En premier lieu, Next.js est un framework qui permet de construire un site en se basant sur la librairie React en offrant une configuration de base pour le développement (avec le fast refresh) et la publication de l'application (bundling & optimization). Il offre aussi des outils comme un routeur et un système d'internationalisation.

Enfin, il offre surtout la possibilité d'avoir un pré-rendu des pages à la compilation (Static Site Generation, SSG) ou lors de la requête (Server Side Rendering, SSR) afin d'optimiser le chargement initial du site.

Le pré-rendu

Un des problèmes que l'on rencontre avec React (et plus largement les framework front-end) est que le rendu initial de la page est plus long qu'un rendu classique, car l'utilisateur doit d'abord charger une page vide avant que le JavaScript puisse récupérer les données et construire le DOM.
Dans le cadre d'un rendu côté client, le processus est le suivant :

  • L'utilisateur demande la page et reçoit une page HTML vide
  • Le CSS et le JavaScript sont chargés
  • Le JavaScript est exécuté et des données sont demandées au serveur
  • Une fois ces données disponibles, le JavaScript va construire la structure de la page
  • L'utilisateur voit la page ✅

Cette approche est nécessairement plus lente qu'un rendu HTML classique :

  • L'utilisateur demande la page et reçoit une page HTML complète,
  • Le CSS est chargé,
  • La page s'affiche ✅.

L'objectif du pré-rendu est d'utiliser le code front-end pour générer une version HTML de la page que l'on va servir à l'utilisateur, et qui lui permettra d'avoir un rendu visuel pendant le chargement du JavaScript :

  • L'utilisateur demande la page et reçoit une page HTML complète,
  • Le CSS est chargé et le JavaScript se charge de manière non bloquante,
  • La page s'affiche (l'utilisateur voit la page) ✅,
  • Le JavaScript a fini d'être chargé et est exécuté (les données sont déjà dans la page) et vient remplacer la structure de la page pour une version interactive (c'est l'étape de réconciliation).

Cette approche permet d'avoir les avantages du rendu côté serveur (référencement et premier chargement rapide du contenu) tout en gardant une navigation côté client dynamique (on ne charge que les données à chaque navigation au lieu de recharger toute la structure HTML).

Les différents types de pré-rendu

Next.js propose de mettre en place facilement ce système de pré-rendu avec plusieurs approches possibles qui peuvent être combinées si nécessaire.

Le rendu statique

Les pages HTML sont générées à la compilation de l'application. Si le site utilise une API, il faudra lui indiquer les différents chemins possibles afin qu'il génère tous les fichiers HTML en amont. Aussi, pour chaque page qui utilise des données externes, un fichier JSON sera généré pour gérer la navigation côté client.

Si un utilisateur charge d'entrée la page d'un article, il chargera un fichier HTML qui contiendra le rendu HTML et les données pour la phase de réconciliation.

<html>
    <head>
        <title>Mon titre</title>
        <script src="app.js" defer></script>
        <link rel="stylesheet" src="app.css" />
    </head>
    <body>
        <main>
            <h1>Mon titre</h1>
            <p>Créé le 19 Février 2020</p>
            <!-- Le code HTML sera directement disponible -->
        </main>
        <!-- Les données nécessaires à la réconciliation -->
        <script id="__NEXT_DATA__" type="application/json">
        {"props":{"pageProps":{"posts":[{"slug":"hello-world","title":"Mon titre","created_at":"2020-02-19T22:50:28.028Z"}}}}
        </script>
    </body>
</html>

En revanche, si l'utilisateur charge la page d'accueil et se rend après coup sur la page d'un article, il chargera alors le fichier JavaScript qui contient la structure de la page et le fichier JSON qui contient les données. S'il continue, un nouvel article seul le JSON sera chargé.

Les avantages du statique

  • Le site est facile à déployer,
  • Le site est rapide.

Inconvénients

  • Les données ne doivent pas changer trop souvent (car il faut reconstruire le site à chaque changement),
  • Le temps de compilation peut être long s'il y a de très nombreuses pages.

Le rendu côté serveur

Dans le cadre de ce rendu chaque page va être générée côté serveur pour chaque requête utilisateur. Si un appel API est nécessaire, il sera fait à chaque fois pour récupérer les données avant de les renvoyer au client.

Les avantages du SSR

  • Les données sont toujours fraîches,
  • Le site peut avoir une infinité de pages.

Inconvénients

  • Le chargement des pages sera plus lent (car il faut contacter l'API pour chaque page),
  • Le déploiement est plus complexe, car il faut NodeJS pour lancer le serveur.

Le rendu statique incrémental

Ce nouveau type de rendu est un système hybride entre le rendu statique et le rendu serveur. Le principe de base est d'avoir un rendu statique qui peut être régénéré à l'exécution.

export async function getStaticProps({ params }) {
    // On peut récupérer des données externes ici
    return {
        props: {
            slug: params.slug,
            updatedAt: Date.now()
        },
        // Next.js va créer un nouveau fichier statique
        // - quand une nouvelle requête arrive
        // - au maximum une fois toutes les 5 secondes
        revalidate: 5
    }
}

Ce système permet de servir un fichier statique à l'utilisateur (ce qui est rapide) tout en ayant un rafraîchissement du contenu plus fréquent.

Les avantages du rendu incrémental

  • Les données sont plus fraîches.
  • Le chargement des pages sera rapide.

Inconvénients

  • Le déploiement est plus complexe, car il faut NodeJS pour lancer le serveur.
  • Le premier utilisateur qui fait la requête verra peut-être une version trop vieille de la page.
Publié
Technologies utilisées
Auteur :
Grafikart
Partager