Découvrez comment accélérer votre application Next.js grâce au fractionnement du code et aux stratégies de chargement intelligentes.
Qu'allez-vous apprendre ?
Cet article décrit les différents types de répartition du code et explique comment utiliser les importations dynamiques pour accélérer vos applications Next.js.
Répartition du code basée sur les routes et les composants
Par défaut, Next.js divise votre code JavaScript en blocs distincts pour chaque route. Lorsque les utilisateurs chargent votre application, Next.js n'envoie que le code nécessaire pour la route initiale. Lorsque les utilisateurs parcourent l'application, ils récupèrent les fragments associés aux autres routes. La division du code basée sur les routes réduit la quantité de script qui doit être analysée et compilée en une seule fois, ce qui accélère le chargement des pages.
Bien que la division du code basée sur les routes soit une bonne option par défaut, vous pouvez optimiser davantage le processus de chargement avec la division du code au niveau du composant. Si votre application comporte des composants volumineux, il est judicieux de les diviser en morceaux distincts. De cette façon, tous les composants volumineux qui ne sont pas critiques ou qui ne s'affichent que lors de certaines interactions utilisateur (comme cliquer sur un bouton) peuvent être chargés de manière différée.
Next.js est compatible avec les import()
dynamiques, ce qui vous permet d'importer des modules JavaScript (y compris des composants React) de manière dynamique et de charger chaque importation en tant que bloc distinct. Vous bénéficiez ainsi d'une division du code au niveau des composants et pouvez contrôler le chargement des ressources afin que les utilisateurs ne téléchargent que le code dont ils ont besoin pour la partie du site qu'ils consultent. Dans Next.js, ces composants sont rendus côté serveur (SSR) par défaut.
Importations dynamiques en action
Cet article inclut plusieurs versions d'une application exemple qui se compose d'une page simple avec un bouton. Lorsque vous cliquez sur le bouton, vous voyez un adorable chiot. À mesure que vous parcourrez chaque version de l'application, vous verrez en quoi les importations dynamiques sont différentes des importations statiques et comment les utiliser.
Dans la première version de l'application, le chiot vit dans components/Puppy.js
. Pour afficher le chiot sur la page, l'application importe le composant Puppy
dans index.js
à l'aide d'une instruction d'importation statique:
import Puppy from "../components/Puppy";
Pour voir comment Next.js regroupe l'application, inspectez la trace réseau dans les outils pour les développeurs:
Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran .
Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir DevTools.
Cliquez sur l'onglet Réseau.
Cochez la case Disable cache (Désactiver le cache).
Actualisez la page.
Lorsque vous chargez la page, tout le code nécessaire, y compris le composant Puppy.js
, est regroupé dans index.js
:
Lorsque vous appuyez sur le bouton Click me (Cliquez ici), seule la requête pour le fichier JPEG du chiot est ajoutée à l'onglet Network (Réseau) :
L'inconvénient de cette approche est que, même si les utilisateurs ne cliquent pas sur le bouton pour voir le chiot, ils doivent charger le composant Puppy
, car il est inclus dans index.js
. Dans cet exemple, ce n'est pas un problème, mais dans les applications réelles, il est souvent très utile de ne charger de grands composants que lorsque cela est nécessaire.
Examinez maintenant une deuxième version de l'application, dans laquelle l'importation statique est remplacée par une importation dynamique. Next.js inclut next/dynamic
, ce qui permet d'utiliser des importations dynamiques pour tous les composants de Next:
import Puppy from "../components/Puppy";
import dynamic from "next/dynamic";
// ...
const Puppy = dynamic(import("../components/Puppy"));
Suivez les étapes du premier exemple pour inspecter la trace réseau.
Lorsque vous chargez l'application pour la première fois, seul index.js
est téléchargé. Cette fois, il est 0,5 ko plus petit (il est passé de 37,9 ko à 37,4 ko), car il n'inclut pas le code du composant Puppy
:
Le composant Puppy
se trouve désormais dans un bloc distinct, 1.js
, qui n'est chargé que lorsque vous appuyez sur le bouton:
Dans les applications réelles, les composants sont souvent beaucoup plus volumineux. Leur chargement différé peut entraîner une réduction de plusieurs centaines de kilo-octets de votre charge utile JavaScript initiale.
Importations dynamiques avec un indicateur de chargement personnalisé
Lorsque vous chargez des ressources de manière différée, nous vous recommandons de fournir un indicateur de chargement en cas de retard. Dans Next.js, vous pouvez le faire en fournissant un argument supplémentaire à la fonction dynamic()
:
const Puppy = dynamic(() => import("../components/Puppy"), {
loading: () => <p>Loading...</p>
});
Pour voir l'indicateur de chargement en action, simulez une connexion réseau lente dans DevTools:
Pour prévisualiser le site, appuyez sur View App (Afficher l'application), puis sur Fullscreen (Plein écran) .
Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir DevTools.
Cliquez sur l'onglet Réseau.
Cochez la case Disable cache (Désactiver le cache).
Dans la liste déroulante Limitation, sélectionnez 3G rapide.
Appuyez sur le bouton Cliquez ici.
Lorsque vous cliquez sur le bouton, le chargement du composant prend un certain temps, et l'application affiche le message "Loading…" (Chargement en cours…) en attendant.
Importations dynamiques sans serveur côté serveur
Si vous devez afficher un composant uniquement côté client (par exemple, un widget de chat), vous pouvez le faire en définissant l'option ssr
sur false
:
const Puppy = dynamic(() => import("../components/Puppy"), {
ssr: false,
});
Conclusion
Grâce à la prise en charge des importations dynamiques, Next.js vous permet de diviser le code au niveau des composants, ce qui peut réduire vos charges utiles JavaScript et améliorer le temps de chargement de l'application. Tous les composants sont affichés par défaut côté serveur. Vous pouvez désactiver cette option si nécessaire.