La plupart des pages Web et des applications sont composées de nombreuses parties différentes. Au lieu d'envoyer tout le code JavaScript qui compose l'application dès le chargement de la première page, diviser le code JavaScript en plusieurs segments améliore les performances de la page.
Cet atelier de programmation vous explique comment utiliser le fractionnement de code pour améliorer les performances d'une application simple qui trie trois nombres.
Mesurer
Comme toujours, il est important de commencer par mesurer les performances d'un site Web avant d'essayer d'ajouter des optimisations.
- 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 l'application.
71,2 ko de code JavaScript pour trier quelques nombres dans une application simple. What gives?
Dans le code source (src/index.js
), la bibliothèque lodash
est importée et utilisée dans cette application. Lodash fournit de nombreuses fonctions utilitaires utiles, mais seule une seule méthode du package est utilisée ici.
Il est courant d'installer et d'importer des dépendances tierces complètes alors qu'une petite partie seulement est utilisée.
Optimiser
Vous pouvez réduire la taille du bundle de plusieurs façons :
- Écrire une méthode de tri personnalisée au lieu d'importer une bibliothèque tierce
- Utiliser la méthode
Array.prototype.sort()
intégrée pour trier numériquement - N'importez que la méthode
sortBy
à partir delodash
et non l'intégralité de la bibliothèque - Télécharger le code de tri uniquement lorsque l'utilisateur clique sur le bouton
Les options 1 et 2 sont des méthodes parfaitement adaptées pour réduire la taille du bundle (et seraient probablement les plus adaptées pour une application réelle). Cependant, ils ne sont pas utilisés dans ce tutoriel à des fins pédagogiques 😈.
Les options 3 et 4 permettent d'améliorer les performances de cette application. Les sections suivantes de cet atelier de programmation couvrent ces étapes. Comme dans tout tutoriel de codage, essayez toujours d'écrire le code vous-même au lieu de le copier-coller.
N'importez que ce dont vous avez besoin
Vous devez modifier quelques fichiers pour n'importer qu'une seule méthode à partir de lodash
.
Pour commencer, remplacez cette dépendance dans package.json
:
"lodash": "^4.7.0",
avec ce qui suit :
"lodash.sortby": "^4.7.0",
Dans src/index.js
, importez maintenant ce module spécifique:
import "./style.css";
import _ from "lodash";
import sortBy from "lodash.sortby";
Modifiez également l'ordre de tri des valeurs :
form.addEventListener("submit", e => {
e.preventDefault();
const values = [input1.valueAsNumber, input2.valueAsNumber, input3.valueAsNumber];
const sortedValues = _.sortBy(values);
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
});
Actualisez l'application, ouvrez les outils de développement et consultez à nouveau le panneau Network (Réseau).
Pour cette application, la taille du bundle a été réduite de plus de quatre fois avec très peu d'efforts, mais il reste encore des améliorations à apporter.
Division du code
webpack est l'un des outils de regroupement de modules Open Source les plus populaires actuellement. En résumé, il groupe tous les modules JavaScript (ainsi que d'autres éléments) qui constituent une application Web dans des fichiers statiques pouvant être lus par le navigateur.
Le seul bundle utilisé dans cette application peut être divisé en deux composants distincts:
- L'un est responsable du code qui constitue notre parcours initial.
- Un bloc secondaire contenant notre code de tri
Grâce aux importations dynamiques, un bloc secondaire peut être chargé de manière différée ou chargé à la demande. Dans cette application, le code qui compose le bloc ne peut être chargé que lorsque l'utilisateur appuie sur le bouton.
Commencez par supprimer l'importation de niveau supérieur pour la méthode de tri dans src/index.js
:
import sortBy from "lodash.sortby";
Importez-le également dans l'écouteur d'événements qui se déclenche lorsque l'utilisateur appuie sur le bouton:
form.addEventListener("submit", e => {
e.preventDefault();
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
La fonctionnalité import()
fait partie d'une proposition (actuellement à l'étape 3 du processus TC39) visant à permettre l'importation dynamique d'un module. Webpack est déjà compatible avec cette fonctionnalité et suit la même syntaxe que celle définie dans la proposition.
import()
renvoie une promesse. Lorsqu'elle est résolue, le module sélectionné est fourni et divisé en un bloc distinct. Une fois le module renvoyé, module.default
est utilisé pour référencer l'exportation par défaut fournie par lodash. La promesse est enchaînée avec un autre .then
qui appelle une méthode sortInput
pour trier les trois valeurs d'entrée. À la fin de la chaîne de promesses,catch()
permet de gérer les cas où la promesse est refusée en raison d'une erreur.
La dernière chose à faire est d'écrire la méthode sortInput
à la fin du fichier. Il doit s'agir d'une fonction qui renvoie une fonction qui exploite la méthode importée à partir de lodash.sortBy
. La fonction imbriquée peut ensuite trier les trois valeurs d'entrée et mettre à jour le DOM.
const sortInput = () => {
return (sortBy) => {
const values = [
input1.valueAsNumber,
input2.valueAsNumber,
input3.valueAsNumber
];
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
};
}
Surveiller
Actualisez l'application une dernière fois et surveillez à nouveau le panneau Réseau. Seul un petit bundle initial est téléchargé dès le chargement de l'application.
Une fois le bouton enfoncé pour trier les nombres saisis, le bloc contenant le code de tri est extrait et exécuté.
Notez que les nombres sont toujours triés.
Conclusion
La division du code et le chargement différé peuvent être des techniques extrêmement utiles pour réduire la taille initiale du bundle de votre application, et cela peut directement réduire considérablement le temps de chargement des pages. Toutefois, certains points importants doivent être pris en compte avant d'inclure cette optimisation dans votre application.
UI de chargement différé
Lorsque vous chargez de manière différée des modules de code spécifiques, il est important de réfléchir à l'expérience des utilisateurs disposant de connexions réseau plus faibles. Si vous divisez et chargez un très grand bloc de code lorsqu'un utilisateur envoie une action, il peut sembler que l'application a cessé de fonctionner. Pensez donc à afficher un indicateur de chargement.
Modules de nœuds tiers à chargement différé
Il n'est pas toujours optimal de charger de manière paresseuse les dépendances tierces dans votre application. Cela dépend de l'endroit où vous les utilisez. En règle générale, les dépendances tierces sont divisées en un bundle vendor
distinct qui peut être mis en cache, car elles ne sont pas mises à jour aussi souvent. Découvrez comment le SplitChunksPlugin peut vous aider dans cette démarche.
Chargement différé avec un framework JavaScript
De nombreux frameworks et bibliothèques populaires qui utilisent webpack fournissent des abstractions pour faciliter le chargement paresseux plutôt que d'utiliser des importations dynamiques au milieu de votre application.
- Modules de chargement différé avec Angular
- Division du code avec React Router
- Chargement différé avec Vue Router
Bien qu'il soit utile de comprendre le fonctionnement des importations dynamiques, utilisez toujours la méthode recommandée par votre framework/bibliothèque pour charger des modules spécifiques en différé.
Préchargement et préchargement
Dans la mesure du possible, exploitez les optimisations de navigateur telles que <link rel="preload">
ou <link rel="prefetch">
pour essayer de charger les modules critiques encore plus tôt. Webpack prend en charge les deux suggestions via l'utilisation de commentaires magiques dans les instructions d'importation. Pour en savoir plus, consultez le guide Précharger des blocs critiques.
Chargement différé de plus que du code
Les images peuvent constituer une part importante d'une application. Le chargement différé des éléments situés en dessous de la ligne de flottaison ou en dehors de la fenêtre d'affichage de l'appareil peut accélérer un site Web. Pour en savoir plus, consultez le guide Lazysizes.