Articles
Sep 19, 2024

Optimisation des performances avec Next.js

7 astuces pour booster vos performances avec NextJS

Optimisation des performances avec Next.js

Introduction


Lorsque l'on développe une appli web, la performance joue un rôle crucial, tant pour l'expérience utilisateur que pour le SEO. Avec Next.js, les optimisations natives apportées par le framework facilitent grandement l'amélioration des performances de vos applications. Dans cet article, nous allons explorer quelques-unes des fonctionnalités de Next.js qui peuvent accélérer considérablement vos projets.

1. Server Components

Les Server Components sont un des changements les plus significatifs dans Next.js 14. Ils permettent de rendre du contenu sur le serveur et de ne pas envoyer de JavaScript inutile au client.

Exemple de page avec Server Components

Avec l’App Directory, le rendu des pages se fait désormais en utilisant le répertoire app/, et les Server Components sont la norme par défaut.

Cela permet par exemple de déléguer au serveur la génération des éléments statiques

export default function HomePage() {
  return (
    <div>
      <h1>Bonjour tout le monde!</h1>
      <p>Ceci est un exemple de page.</p>
    </div>
  );
}

Vous pouvez y exécuter des fonctions asynchrones (nous détaillerons plus loin)

// app/page.js
export default async function HomePage() {
  const data = await fetch('https://api.example.com/data').then(async (res) => await res.json());
  return (
    <div>
      <h1>Données rendues côté serveur</h1>    
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

Dans cet exemple, la page est générée entièrement côté serveur, et aucun JavaScript n'est envoyé au client. Cela améliore les temps de chargement en réduisant la taille des bundles JavaScript.

Avantages des Server Components

  • Moins de JavaScript côté client : Seul le HTML est envoyé, ce qui réduit la taille du bundle et améliore les performances.
  • Préchargement des données côté serveur : Comme avec getServerSideProps, mais sans besoin de méthode spécifique, les Server Components récupèrent les données côté serveur et les affichent directement.
Comme il s'agit de composants générés côté serveur, vous ne pouvez pas y utiliser de manipulation de leurs état. Donc, pas de useState ou de useEffect ici !

2. Optimisation des images avec next/image

L'optimisation des images est toujours un élément clé dans Next.js 14. Le composant next/image fonctionne toujours, mais avec les Server Components, il peut être utilisé encore plus efficacement.

import Image from 'next/image';
export default function MyImageComponent() {
  return (
    <div>
      <h2>Optimisation des images avec Next.js 14</h2>
      <Image
        src="/images/monimage.jpg"
        alt="Mon Image Optimisée"
        width={500}
        height={300}
        placeholder="blur"
        blurDataURL="/images/blur-image.jpg"
      />

    </div>
  );
}


Ce que fait next/image :

  • Lazy loading automatique : Les images ne sont chargées que lorsqu'elles apparaissent à l'écran.
  • Optimisation des formats : Next.js choisit automatiquement le meilleur format d'image (JPEG, WebP, etc.).
  • Gestion des dimensions : Les tailles des images sont adaptées à l'affichage pour réduire la consommation de bande passante

.

3. Data Fetching avec les Server Components

Avec l'App Directory, le data fetching est plus intégré dans les Server Components. Vous pouvez directement utiliser des requêtes dans le composant sans avoir besoin d'un mécanisme externe comme getStaticProps ou getServerSideProps.

Exemple avec fetch côté serveur

// app/posts/page.js
export default async function PostsPage() {
  const posts = await fetch('https://jsonplaceholder.typicode.com/posts').then((res) => res.json());
  return (
    <div>
      <h1>Liste des articles</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

Dans cet exemple, nous récupérons des données directement dans le composant Server Side, et le contenu est rendu côté serveur.

Vous pouvez ajuster les options de mise en cache grâce à la surcouche de fetch exposée par NextJS. 


Je vous laisse consulter la doc pour cela :
https://nextjs.org/docs/app/api-reference/functions/fetch

4. SSR et Link component

La méthode Server Side Rendering permet de déléguer le rendu du contenu HTML CSS côté serveur. C'est ce que nous faisons par defaut lorsque nous utilisons les Server Component. Lorsque vous arrivez sur une page, c'est le serveur qui se charge de générer le contenu et de le fournir (oui oui, comme dans les années 2000 !).

Un système de cache permet de rendre la page instantanément à partir de la seconde visite de la page. 

Mais nous pouvons améliorer cela en demandant à Next JS de prérendre la page avant même que le visiteur n'ai l'intention d'y aller. 

Créez un composant nommé PrefetchLink dans votre projet

import Link, { LinkProps } from 'next/link';
import React from 'react';

const PrefetchedLink = React.forwardRef<HTMLAnchorElement, LinkProps>(({ ...props }, ref) => {
  return <Link prefetch={true} {...props} ref={ref} />;
});

export default PrefetchedLink;

Une seule petite instruction : "prefetch={true}" permet à Next de commencer le rendu de la page ciblé au moment où le lien apparait dans le viewport. 

Contrairement à ce que l'on pourrait penser, cette option n'est pas à true par défaut ! C'est bien à vous de la préciser

5. Static Site Generation et generateStaticParams

Le prefetch c'est déjà super, mais nous pouvons aller encore plus loin !

La SSG est utilisée pour générer des pages statiques lors de la compilation du projet. Cela signifie qu'au lieu que ce soit le(les) utilisateur(s) qui demandent au serveur de prégénérer une page lors de leur navigation, c'est au moment du build du projet que vous aller déjà prérendre ces pages. 

Cela est très utile par exemple pour des pages avec de la donnée dynamique issue du backend mais qui ne change pas en fonction de l'utilisateur. 

Une liste d'articles de blog par exemple. 

Voici comment procéder :

app/blog/[slug]/page.js

// Return a list of `params` to populate the [slug] dynamic segment
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
 
  return posts.map((post) => ({
    slug: post.slug,
  }))
}
 
// Multiple versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
export default function Page({ params }) {
  const { slug } = params
  // ...
}

6. Data Fetching et Suspense

Avec Next.js 14, vous pouvez également utiliser React Suspense pour un rendu asynchrone, ce qui améliore encore les performances en permettant de différer le rendu de certaines parties de la page jusqu'à ce que les données soient prêtes.

import { Suspense } from 'react';
function Loading() {
  return <p>Chargement...</p>;
}
async function PostsList() {
  const posts = await fetch('https://jsonplaceholder.typicode.com/posts').then((res) => res.json());
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
export default function PostsPage() {
  return (
    <div>
      <h1>Liste des articles</h1>
      <Suspense fallback={<Loading />}>
        <PostsList />
      </Suspense>
    </div>
  );
}


Avantages du Suspense

  • Rendu asynchrone : Le contenu peut être rendu partiellement, ce qui améliore l'expérience utilisateur en affichant du contenu dès que possible.
  • Meilleure gestion des données : Vous pouvez gérer plusieurs sources de données de manière efficace sans bloquer l'affichage de la page.

7. Optimisation des ressources CSS et JavaScript

Code Splitting automatique

Avec Next.js 14, le code splitting est automatique pour les composants et les dépendances. Cela signifie que seul le code nécessaire à une page spécifique est chargé, ce qui améliore les temps de chargement.

Vous n’avez rien à faire de particulier ici, Next.js prend en charge le code splitting de manière transparente. Cependant, vous pouvez observer la taille de vos bundles et optimiser les dépendances.

next build --analyze

Ce code vous permettra de visualiser un graphique de la taille des différents bundles et de voir où des optimisations peuvent être effectuées.

Conclusion

Avec Next.js 14 et le nouveau App Directory, le framework offre des outils puissants pour optimiser les performances de vos applications. Entre les Server Components, l’optimisation automatique des images et des ressources, et la gestion asynchrone des données, il est plus facile que jamais de construire des applications rapides et efficaces.

Si vous ne l'avez pas encore fait, je vous encourage à explorer cette nouvelle version et à intégrer ces fonctionnalités dans vos projets !