Chargement différé (Lazy Loading)
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 différer 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 :
- En utilisant les importations dynamiques avec
next/dynamic
- 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 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/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'appeldynamic()
pour que Next.js puisse faire correspondre les bundles webpack / les identifiants de module à l'appeldynamic()
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 retournée par import()
:
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 APIs navigateur comme window
.
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 est uniquement chargé dans le navigateur après que l'utilisateur a saisi dans le champ de 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>
)
}