lazy vous permet de différer le chargement du code d’un composant jusqu’à son premier affichage effectif.

const SomeComponent = lazy(load)

Référence

lazy(load)

Appelez lazy en-dehors de vos composants pour déclarer un composant React chargé à la demande :

import { lazy } from 'react';

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

Voir d’autres exemples ci-dessous.

Paramètres

  • load : une fonction qui renvoie une promesse ou un thenable (un objet doté d’une méthode then compatible). React n’appellera pas load tant que vous ne tenterez pas d’afficher le composant renvoyé. Après que React a appelé load pour la première fois, il patientera pour que la promesse s’établisse, puis affichera la propriété ,.default de la valeur accomplie comme composant React. Tant la promesse renvoyée que sa valeur accomplie seront mises en cache, et React ne rappellera pas load. Si la promesse rejette, React lèvera (throw) la raison du rejet (généralement une Error) pour que le périmètre d’erreur le plus proche la gère.

Valeur renvoyée

lazy renvoie un composant React que vous pouvez afficher dans votre arborescence. Pendant que le code du composant chargé à la demande se charge, toute tentative de l’afficher suspend. Utilisez <Suspense> pour afficher un indicateur de chargement pendant ce temps-là.


La fonction load

Paramètres

load ne prend aucun paramètre.

Valeur renvoyée

Vous aurez besoin de renvoyer une promesse ou un thenable (un objet doté d’une méthode then compatible). La valeur accomplie doit finalement posséder une propriété .default qui se comporte comme un composant React valide, tel une qu’une fonction, un composant memo, ou un composant forwardRef.


Utilisation

Charger des composants à la demande avec Suspense

En général, vous importez vos composants avec la déclaration statique import :

import MarkdownPreview from './MarkdownPreview.js';

Pour différer le chargement du code de ce composant jusqu’à ce qu’il affiche pour la première fois, remplacez cette importation avec :

import { lazy } from 'react';

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

Ce code s’appuie sur l’importation dynamique import(),, ce qui peut nécessiter une prise en charge de votre bundler ou framework. Pour utiliser cette approche, le composant chargé à la demande que vous importez doit être exporté sous le nom default (ce qui est notamment le cas de l’export par défaut).

Maintenant que le code de votre composant se charge à la demande, vous aurez besoin de spécifier ce qui devrait être affiché pendant son chargement. Vous pouvez le faire en enrobant le composant chargé à la demande ou l’un de ses parents dans un périmètre <Suspense> :

<Suspense fallback={<Loading />}>
<h2>Aperçu</h2>
<MarkdownPreview />
</Suspense>

Dans cet exemple, le code de MarkdownPreview ne sera pas chargé jusqu’à ce que vous essayiez de l’afficher. Si MarkdownPreview n’est pas encore chargé, Loading sera affiché à sa place. Essayez de cocher la case :

import { useState, Suspense, lazy } from 'react';
import Loading from './Loading.js';

const MarkdownPreview = lazy(() => delayForDemo(import('./MarkdownPreview.js')));

export default function MarkdownEditor() {
  const [showPreview, setShowPreview] = useState(false);
  const [markdown, setMarkdown] = useState('Salut **tout le monde** !');
  return (
    <>
      <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} />
      <label>
        <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} />
        Afficher l’aperçu
      </label>
      <hr />
      {showPreview && (
        <Suspense fallback={<Loading />}>
          <h2>Aperçu</h2>
          <MarkdownPreview markdown={markdown} />
        </Suspense>
      )}
    </>
  );
}

// Ajouter un délai fixe pour voir l’état de chargement
function delayForDemo(promise) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  }).then(() => promise);
}

Cette démo se charge avec un retard artificiel. La prochaine fois que vous décochez et cochez la case, Preview sera mis en cache, il n’y aura donc pas d’état de chargement. Pour voir à nouveau l’état de chargement, cliquez sur « Réinitialiser » dans le bac à sable.

En savoir plus sur la gestion des états de chargement avec Suspense.


Dépannage

L’état de mon composant lazy est réinitialisé de façon inattendue

Ne déclarez pas les composants lazy à l’intérieur d’autres composants :

import { lazy } from 'react';

function Editor() {
// 🔴 Erroné : ça entraînera la réinitialisation de tous les états lors des réaffichages
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
// ...
}

Déclarez-les toujours plutôt au début de votre module :

import { lazy } from 'react';

// ✅ Correct : déclarez les composants lazy en-dehors de vos composants
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

function Editor() {
// ...
}