Fermer

novembre 4, 2020

Chargement paresseux de votre application React


Améliorez les performances de votre application React avec React.lazy et Suspense.

Si vous créez une application Web aujourd'hui, il y a de fortes chances que vous utilisiez un framework JavaScript tel que React, avec un tas d'autres bibliothèques comme React Router ou Kendo UI . Nous oublions souvent de prendre en compte le coût d'envoi de tout ce JavaScript à nos utilisateurs. Selon l'équipe V8 de Google dans son rapport « The cost of JavaScript 2019 », jusqu'à 30% du temps de chargement d'une page sont consacrés à l'exécution de JavaScript.

JavaScript est toujours la ressource la plus chère que nous envoyons aux téléphones mobiles, car cela peut retarder considérablement l'interactivité.

– Addy Osmani

Dans cet article, nous allons discuter de la façon dont nous pouvons améliorer les performances de nos applications en ne chargeant que le JavaScript dont l'utilisateur a besoin. à un moment donné, réduisant la quantité de code à télécharger et à exécuter lors du chargement de la page, et rendant l'application plus interactive.

Nous utiliserons React.lazy et Suspense pour retarder le chargement d'un composant complexe comme KendoReact's StockChart jusqu'à ce qu'un bouton soit cliqué.

 Exemple d'application utilisant React.lazy and Suspense

Vous pouvez voir le code pour l'application dans ce dépôt GitHub .

Comprendre ding Dynamic Imports

Au lieu d'envoyer un gros paquet avec tout le code de notre application lors du chargement initial de la page, nous pouvons envoyer des paquets plus petits au fur et à mesure que l'utilisateur interagit avec l'application. Pour ce faire, nous nous appuyons sur une fonctionnalité JavaScript moderne appelée importations dynamiques . Une importation dynamique renvoie une promesse qui se résoudra une fois que le module requis sera transféré sur le réseau, et sera analysée et exécutée par le moteur JavaScript.

Une importation statique ressemble à ceci:

 import   { concat }   de   "./ utils" ; 

console .  log  ( concat  ( "A"   "B"   "C"  ) ) ; 

Alors qu'une importation dynamique ressemble à ceci:

 import  ( "./ utils" ) .  then  ] ( utils  =>   {
  console .  log  ( utils .  concat  ( "A"   "B" [19659018] "C" ) ) ; 
} ) ; 

Outils comme Create React App et webpack comprenez ce que nous essayons de faire avec ces importations dynamiques et produira des fichiers JavaScript séparés pour ces bundles chargés paresseusement. Si nous configurons nous-mêmes webpack, il peut être judicieux de passer un peu de temps à lire la documentation de webpack sur la division de code .

Lazy-Loading avec React.lazy et Suspense

À partir de la version 16.6, React inclut une fonction intégrée React.lazy qui permet de diviser très facilement une application en composants à chargement différé à l'aide d'importations dynamiques. [19659004] Vous pouvez transformer ceci:

 import  StockChartContainer  from   "./ StockChartContainer" ; 

En ceci:

 const  StockChartContainer  = [19659067] lazy  ( ()   =>   import  ( "./ StockChartContainer" ) ) ; 

Et React chargera automatiquement le bundle contenant notre composant StockChartContainer lorsque nous essaierons de le rendre pour la première fois.

Nous voudrons encapsuler th est un composant paresseux dans un composant Suspense qui nous permettra d'afficher du contenu de secours pendant le chargement des choses. Voyons à quoi cela ressemble.

Exemple

Dans cet exemple, nous allons charger un composant complexe contenant KendoReact's StockChart mais seulement après que l'utilisateur clique sur un bouton. De cette façon, nous éviterons d'envoyer à l'utilisateur plus de code qu'il n'en a besoin lors du chargement initial.

Nous allons stocker l'état pour savoir si notre composant complexe doit être affiché:

 class   App   extend [19659085] Composant   {
   constructeur  ( props )   {
     super  ( props ) ; 

     cet .  état  =   {
      showChart :   false 
    } ; 
  } 
} 

Ensuite, nous implémenterons une fonction handleClick qui basculera l'état lorsque l'utilisateur clique sur un bouton:

 class   App   extend   Component   {
  

   handleClick   =   ()   =>   {[19659092] this .  setState  ( prevState  =>   ( {
      showChart :  !  prevState .  showChart
    } ) ) ; 
  } ; 
} 

Il suffit maintenant de tout rassembler dans la méthode render :

 const  StockChartContainer  =   paresseux  ( ()   =>   import  ( "./ StockChartContainer" ) ) ; 

 class   App   extend   Component   {
  

   render  ()   {[19659092] const   { showChart }   =   this .  state ; 
     const  buttonText  =  showChart ?   "Masquer le graphique boursier"  :   "Afficher le graphique boursier" ; 
     const  chartComponent  =  showChart ? [19659071] < StockChartContainer  / >  :   null ; 
     const  loadingCompo nent  =   < div >  Chargement  ...  < /  div > ; 

     return   (
       < div className  =  "App" > 
         < header className  =  "App-header" [19659162]> 
           < h1 className  =  "App-title" >  Stock Chart  < /  h1 > [19659179] < div className  =  "App-button" > 
             < Button primary  =  { true }  onClick  =  { this .  handleClick } > 
               { buttonText } 
             < /  Bouton > 
           < /  div > 
         < /  header > 
         < div className  =  "App-chart" > 
           < Suspense fallback  =  { loadingComponent } >  { chartComponent }  < /  Suspense > 
         < /  div > 
       < /  div > 
    ) ; 
  } [19659053]} 

Voyons si cela a fonctionné. Si nous ouvrons Chrome DevTools, cliquez sur l'onglet Network et rechargez la page, nous verrons les bundles que nous envoyons lors du chargement initial:

 Bundles on initial load [19659004] Si nous cliquons maintenant sur le bouton «Afficher le graphique boursier», nous verrons que plus de lots sont transférés juste avant que notre graphique ne s'affiche:

Nous avons pu retarder le téléchargement et l'exécution de tous ce code jusqu'à ce que l'utilisateur en ait besoin. Génial!

Conclusion

Si nous envoyons trop de JavaScript à nos utilisateurs, nous alourdirons le fil de discussion principal du navigateur et il ne pourra pas répondre aux interactions des utilisateurs. Les composants de chargement paresseux de notre application qui ne sont pas nécessaires lors du chargement initial de la page aideront à réduire la quantité de travail que le navigateur doit effectuer, ce qui réduira notre temps d'interactivité et offrira une meilleure expérience à nos utilisateurs, en particulier ceux sur les appareils mobiles. React.lazy et Suspense rendent la tâche si facile que nous n'avons vraiment aucune excuse!




Source link