Comment charger à la demande les composants clients et les bibliothèques

Le chargement différé dans Next.js aide à améliorer les performances de chargement initial d'une application en réduisant la quantité de JavaScript nécessaire pour rendre une route.

Il vous permet de reporter le chargement des composants clients et des bibliothèques importées, et de ne les inclure dans le bundle client que lorsqu'ils sont nécessaires. Par exemple, vous pourriez vouloir différer le chargement d'une modale jusqu'à ce qu'un utilisateur clique pour l'ouvrir.

Il existe deux façons d'implémenter le chargement différé dans Next.js :

  1. En utilisant les importations dynamiques avec next/dynamic
  2. En utilisant React.lazy() avec Suspense

Par défaut, les composants serveur sont automatiquement découpés en morceaux (code split), et vous pouvez utiliser le streaming pour envoyer progressivement des parties de l'interface du serveur vers le client. Le chargement différé s'applique aux composants clients.

next/dynamic

next/dynamic est une combinaison de React.lazy() et de Suspense. Il se comporte de la même manière dans les répertoires app et pages pour permettre une migration progressive.

Exemples

En utilisant next/dynamic, le composant d'en-tête ne sera pas inclus dans le bundle JavaScript initial de la page. La page affichera d'abord le fallback de Suspense, suivi du composant Header lorsque la limite Suspense est résolue.

import dynamic from 'next/dynamic'

const DynamicHeader = dynamic(() => import('../components/header'), {
  loading: () => <p>Chargement...</p>,
})

export default function Home() {
  return <DynamicHeader />
}

Bon à savoir : Dans import('chemin/vers/le/composant'), le chemin doit être explicitement écrit. Il ne peut pas s'agir d'une chaîne de modèle ni d'une variable. De plus, l'import() doit être à l'intérieur de l'appel dynamic() pour que Next.js puisse faire correspondre les bundles webpack / les identifiants de module à l'appel dynamic() spécifique et les précharger avant le rendu. dynamic() ne peut pas être utilisé à l'intérieur du rendu React car il doit être marqué au niveau supérieur du module pour que le préchargement fonctionne, similairement à React.lazy.

Avec des exports nommés

Pour importer dynamiquement un export nommé, vous pouvez le retourner depuis la Promise renvoyée par import() :

components/hello.js
export function Hello() {
  return <p>Bonjour !</p>
}

// pages/index.js
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() =>
  import('../components/hello').then((mod) => mod.Hello)
)

Sans SSR

Pour charger dynamiquement un composant côté client, vous pouvez utiliser l'option ssr pour désactiver le rendu côté serveur. Ceci est utile si une dépendance externe ou un composant repose sur des API navigateur comme window.

'use client'

import dynamic from 'next/dynamic'

const DynamicHeader = dynamic(() => import('../components/header'), {
  ssr: false,
})

Avec des bibliothèques externes

Cet exemple utilise la bibliothèque externe fuse.js pour la recherche floue. Le module n'est chargé dans le navigateur qu'après que l'utilisateur a saisi une recherche.

import { useState } from 'react'

const names = ['Tim', 'Joe', 'Bel', 'Lee']

export default function Page() {
  const [results, setResults] = useState()

  return (
    <div>
      <input
        type="text"
        placeholder="Rechercher"
        onChange={async (e) => {
          const { value } = e.currentTarget
          // Charge dynamiquement fuse.js
          const Fuse = (await import('fuse.js')).default
          const fuse = new Fuse(names)

          setResults(fuse.search(value))
        }}
      />
      <pre>Résultats : {JSON.stringify(results, null, 2)}</pre>
    </div>
  )
}

On this page