Nouveau : Datasets open source gratuits disponibles !Decouvrir →
Avance 25 min Next.js

Optimiser les performances Next.js

Pourquoi Optimiser les performances Next.js ?

Dans un environnement où l'expérience utilisateur est la clé, l'optimisation des performances de votre application est essentielle. En tant que développeur senior Next.js, vous savez bien que même une petite amélioration peut faire une différence significative. Un cas concret serait le développement d'une plateforme e-commerce : même un délai de quelques centièmes de seconde peut entraîner une baisse considérable des conversions.

Prerequis

  • Connaissances nécessaires :

    • Familiarité avec Next.js
    • Compréhension de la gestion des composants React
    • Connaissance des concepts de routing et de state management (useState, useContext)
    • Expérience avec les hooks personnalisés
  • Outils à installer :

    • Node.js (v14.0.0 ou plus tard)
    • npm (v6.0.0 ou plus tard)
    • Yarn (v1.22.0 ou plus tard) [Optionnel]
    • Editor de code (VSCode recommandé)

Concepts fondamentaux

1. Pre-rendering

Le pre-rendering est une technique où Next.js génère des pages HTML statiques à l'avance lors du build, plutôt que de les rendre au serveur ou côté client.

Schéma mental :

[Build] -> [HTML Statique]

Code fonctionnel :

// pages/index.js
import { useEffect } from 'react';

const Home = () => {
  useEffect(() => {
    console.log('Page rendered at build time');
  }, []);

  return <div>Welcome to the Next.js App!</div>;
};

export default Home;

2. Server-Side Rendering (SSR)

Le SSR génère le HTML côté serveur pour chaque requête entrante.

Schéma mental :

[Request] -> [Render on Server] -> [HTML Sent to Client]

Code fonctionnel :

// pages/about.js
import { useState, useEffect } from 'react';

const About = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);

  return (
    <div>
      {data ? <p>{data.message}</p> : <p>Loading...</p>}
    </div>
  );
};

export default About;

3. Static Generation with Data Fetching

Combinant le pre-rendering statique et les données dynamiques, Next.js vous permet de générer des pages statiques au build avec des données dynamiques.

Schéma mental :

[Build] -> [HTML with Dynamic Data]

Code fonctionnel :

// pages/posts/[id].js
import { useEffect, useState } from 'react';

const Post = ({ post }) => {
  const [data, setData] = useState(post);

  useEffect(() => {
    fetch(`https://api.example.com/posts/${post.id}`)
      .then(response => response.json())
      .then(data => setData(data));
  }, [post.id]);

  return (
    <div>
      {data ? <p>{data.title}</p> : <p>Loading...</p>}
    </div>
  );
};

export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();

  return {
    paths: posts.map(post => `/posts/${post.id}`),
    fallback: false,
  };
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`);
  const post = await res.json();

  return { props: { post } };
}

Mise en pratique : projet fil rouge

Mini-projet réaliste : Gestionnaire de tâches

Étape 1 : Configuration du projet

npx create-next-app@latest task-manager
cd task-manager
npm install react-hook-form @tanstack/react-query

Étape 2 : Création des composants

components/TaskList.js

import { useEffect, useState } from 'react';
import axios from 'axios';

const TaskList = () => {
  const [tasks, setTasks] = useState([]);

  useEffect(() => {
    fetch('http://localhost:3001/tasks')
      .then(response => response.json())
      .then(data => setTasks(data));
  }, []);

  return (
    <div>
      {tasks.map(task => (
        <div key={task.id}>
          <h3>{task.title}</h3>
          <p>{task.description}</p>
        </div>
      ))}
    </div>
  );
};

export default TaskList;

components/TaskForm.js

import { useForm } from 'react-hook-form';

const TaskForm = () => {
  const { register, handleSubmit, reset } = useForm();

  const onSubmit = data => {
    axios.post('http://localhost:3001/tasks', data)
      .then(() => {
        alert('Task added successfully');
        reset();
      });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('title')} placeholder="Title" required />
      <textarea {...register('description')} placeholder="Description" required />
      <button type="submit">Add Task</button>
    </form>
  );
};

export default TaskForm;

Étape 3 : Structure des fichiers

pages/index.js

import TaskList from '../components/TaskList';
import TaskForm from '../components/TaskForm';

const Home = () => {
  return (
    <div>
      <h1>Task Manager</h1>
      <TaskForm />
      <TaskList />
    </div>
  );
};

export default Home;

Étape 4 : Démarrez le serveur

npm run dev

Erreurs fréquentes et debugging

1. Error: Cannot find module 'react-hook-form'

Code incorrect :

import useHookForm from 'react-hook-form'; // Error

Code correct :

import { useForm } from 'react-hook-form'; // Correct

2. TypeError: Cannot read property 'data' of undefined

Code incorrect :

const { data } = useQuery('tasks', fetchTasks); // Error if fetchTasks is not defined

Code correct :

import { useQuery } from '@tanstack/react-query';

const fetchTasks = async () => {
  const response = await axios.get('http://localhost:3001/tasks');
  return response.data;
};

const { data, isLoading } = useQuery('tasks', fetchTasks); // Correct

3. TypeError: Cannot read property 'title' of undefined

Code incorrect :

<div>{task.title}</div> // Error if task is not defined

Code correct :

<div>{task ? task.title : 'Loading...'}</div> // Correct

Pour aller plus loin

  1. Optimisation des images avec Next.js : Documentation
  2. Utilisation de react-query pour la gestion de données asynchrones : Documentation
  3. Création d'un CLI tool avec Next.js : Documentation

Défi pratique

Construire une application simple de gestion de contacts en utilisant les concepts appris, notamment le pre-rendering statique et le server-side rendering.

Besoin d'aide sur Next.js ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Quelle est la différence entre Static Generation (SSG) et Server-Side Rendering (SSR) dans Next.js?
Dans Next.js, Static Generation (SSG) génère le contenu du site avant son déploiement, ce qui rend les pages statiques et les SEO-friendly. Server-Side Rendering (SSR), en revanche, génère chaque page à la demande côté serveur, offrant une meilleure expérience utilisateur pour les applications dynamiques.
Comment optimiser l'utilisation des composants dans un projet Next.js?
Pour optimiser le rendu de vos composants dans Next.js, vous pouvez utiliser React.memo pour éviter les re-rendus inutiles. De plus, lazy loading avec `React.lazy` et `Suspense` peut aider à améliorer la performance en chargeant uniquement les composants nécessaires.
Quelles sont les meilleures pratiques pour la gestion des images dans Next.js?
Pour gérer efficacement les images dans Next.js, vous pouvez utiliser le module built-in `next/image`. Cela permet de charger des images de manière optimisée en utilisant la compression et le lazy loading par défaut. De plus, vous pouvez spécifier différentes tailles d'images pour différents appareils.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.