Comment utiliser React.lazy et Suspense pour le chargement différé des composants

React 16.6 a amené le fractionnement de code à un nouveau niveau. Vous pouvez maintenant charger vos composants quand c'est vraiment nécessaire sans installer de bibliothèques supplémentaires.

Que sont le partage de code et le chargement paresseux?

Webpack définit le fractionnement de code comme:

«Technique de fractionnement de votre code en différents bundles qui peuvent ensuite être chargés à la demande ou en parallèle». [La source]

Une autre façon de dire: «chargement à la demande ou en parallèle» est le chargement paresseux .

En face du chargement paresseux, il y a un chargement impatient . Ici, tout est chargé, que vous l'utilisiez ou non.

Pourquoi utiliserions-nous le partage de code et le chargement paresseux?

Parfois, nous devons introduire un gros morceau de code pour couvrir certaines fonctionnalités. Ce code peut importer une dépendance tierce ou l'écrire seul. Ce code affecte alors la taille du bundle principal.

Le téléchargement de quelques Mo est un jeu d'enfant pour la vitesse Internet actuelle. Nous devons encore penser aux utilisateurs avec une connexion Internet lente ou utilisant des données mobiles.

Comment était-ce fait avant React 16.6?

La bibliothèque la plus populaire pour le chargement différé des composants React est probablement react-loadable.

Il est important que reactjs.org recommande toujours react-loadablesi votre application est rendue sur le serveur. [La source]

react-loadableest en fait assez similaire à la nouvelle approche de React. Je vais le montrer dans la démo suivante.

Quelque chose est-il nécessaire pour la configuration?

Voyons ce que reactjs.org a à dire à ce sujet:

"Si vous utilisez Create React App, Next.js, Gatsby ou un outil similaire, vous disposerez d'une configuration Webpack prête à l'emploi pour regrouper votre application. Si ce n'est pas le cas, vous devrez configurer le regroupement vous-même . Par exemple, consultez les guides d'installation et de mise en route dans la documentation Webpack. "

- reactjs.org

Ok, donc Webpack est requis, qui gère les importations dynamiques des bundles.

La démo suivante est générée en utilisant Create React App.Et dans ce cas, Webpack est déjà configuré et nous sommes prêts à partir.

DEMO

Pour cette démo, nous utiliserons react-pdf. react-pdfest une bibliothèque géniale utilisée pour créer des fichiers PDF sur le navigateur, le mobile et le serveur. Nous pourrions générer un PDF sur le serveur, mais si nous préférons le faire côté client, cela a un coût: la taille du bundle.

J'utilise l'extension de coût d'importation pour Visual Studio Code pour voir les tailles des bibliothèques utilisées.

Disons que notre exigence est de générer un fichier PDF lorsqu'un utilisateur clique sur le bouton.

Maintenant, il s'agit d'un formulaire simple avec un seul cas d'utilisation. Essayez d'imaginer une énorme application Web où ce n'est qu'une fraction des possibilités. Peut-être que cette fonctionnalité n'est pas utilisée très souvent par les utilisateurs.

Mettons-nous dans cette situation. La génération de PDF n'est pas utilisée très souvent et cela n'a pas de sens de charger tout le code pour chaque demande de page.

Je vais essayer de montrer comment nous pouvons développer une solution avec et sans chargement paresseux.

Vitrine de chargement paresseux Eager VS

Dans les deux cas, nous utiliserons un composant qui importe les dépendances à partir d' react-pdfun simple document PDF et le rend.

Rien de spectaculaire ici. Nous importons PDFViewer, Document, Page, Text, à Viewpartir react-pdf. Ceux-ci sont tous utilisés dans la renderméthode du PDFPreviewcomposant.

PDFPreviewreçoit un seul propappelé title. Comme son nom l'indique, il est utilisé comme titre dans un fichier PDF nouvellement généré.

pdfStyles.js ressemble à ceci:

Chargement avide

Voyons d'abord à quoi pourrait ressembler le composant parent sans chargement différé:

qui rend la vue suivante dans le navigateur:

Passons en revue le code ensemble:

Sur la ligne 2, nous importons le PDFPreviewcomposant.

À la ligne 6, nous initialisons l'état avec les valeurs par défaut. nameest un champ utilisé comme titre dans le fichier PDF, tandis que field PDFPreviewest un booléen qui affiche ou masque PDFPreview.

Maintenant, passons à la renderméthode et vérifions ce qui sera rendu.

Aux lignes 19 et 25, nous rendons une entrée et un bouton. Lorsque l'utilisateur tape dans l'entrée, namel'état est modifié.

Ensuite, lorsqu'un utilisateur clique sur "Générer PDF", showPDFPreviewest défini sur true. Le composant effectue un nouveau rendu et affiche le PDFPreviewcomposant.

Même si nous n'utilisons PDFPreviewque sur clic de l'utilisateur, tout le code qui lui est associé est inclus dans le bundle d'applications:

C'est un environnement de développement. En production, les tailles seraient nettement plus petites. Pourtant, nous ne divisons pas le code de manière optimale.

Chargement paresseux

Nous n'avons fait que de petits changements et passons en revue.

La ligne 2 est remplacée par:

const LazyPDFDocument = React.lazy(() => import("./PDFPreview"));

Voyons ce que la documentation React dit à propos de React.lazy:

React.lazyprend une fonction qui doit appeler une dynamique import(). Cela doit renvoyer un Promisequi se résout en un module avec une defaultexportation contenant un composant React.

- reactjs.org

À la ligne 27, nous utilisons Suspense, qui doit être un parent d'un composant chargé paresseusement. Quand showPDFPreviewest défini sur true, LazyPDFDocumentcommence à se charger.

Jusqu'à ce que le composant enfant soit résolu, Suspenseaffiche tout ce qui est fourni à fallbackprop.

Le résultat final ressemble à ceci:

Nous pouvons voir les poids de 0.chunk.js nettement moins qu'avant et 4.chunk.js et 3.chunk.js sont chargés en appuyant sur un bouton.

Conclusion

Chaque fois que nous introduisons une nouvelle dépendance dans notre projet, notre responsabilité est d'évaluer son coût et de vérifier comment il affecte le bundle principal.

Ensuite, nous devons nous demander si cette fonctionnalité sera rarement utilisée et pouvons-nous la charger à la demande sans sacrifier l'expérience utilisateur.

Si la réponse est oui, alors React.Lazyet Suspensevraiment nous aider dans cette tâche.

Merci pour la lecture! Veuillez le partager avec toute personne qui pourrait le trouver utile et laisser des commentaires.