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é.
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:
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