Réduire les charges utiles JavaScript avec le fractionnement de code

La plupart des pages Web et des applications sont constituées de nombreuses parties différentes. Au lieu de l'envoi de tout le code JavaScript qui compose l'application dès le premier est chargée, diviser le code JavaScript en plusieurs fragments améliore les performances des pages.

Cet atelier de programmation vous montre comment utiliser la scission du code pour améliorer les performances une application simple qui trie trois nombres.

Fenêtre de navigateur affichant une application intitulée "Magic Sorter" (Tri magique) avec trois champs de saisie de chiffres et un bouton de tri.

Mesurer

Comme toujours, il est important de commencer par mesurer les performances d'un site Web avant pour tenter d'ajouter des optimisations.

  1. Pour prévisualiser le site, appuyez sur Afficher l'application. Appuyez ensuite sur Plein écran plein écran
  2. Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir les outils de développement.
  3. Cliquez sur l'onglet Réseau.
  4. Cochez la case Disable cache (Désactiver le cache).
  5. Actualisez l'application.

Panneau "Network" (Réseau) affichant le bundle JavaScript de 71,2 ko

71,2 Ko de code JavaScript juste 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 nombreux utilitaires utiles mais une seule méthode du package est utilisée ici. L’installation et l’importation de dépendances tierces complètes dans lesquelles seule une petite utilisée est une erreur courante.

Optimiser

Il existe plusieurs façons de réduire la taille du lot:

  1. Écrire une méthode de tri personnalisée au lieu d'importer une bibliothèque tierce
  2. Utiliser la méthode Array.prototype.sort() intégrée pour trier numériquement
  3. N'importez la méthode sortBy que depuis lodash, et non l'intégralité de la bibliothèque.
  4. Télécharger le code pour le tri uniquement lorsque l'utilisateur clique sur le bouton

Les options 1 et 2 sont des méthodes parfaitement appropriées pour réduire la taille du paquet (et serait probablement la plus logique pour une application réelle). Cependant, il s'agit qui n'ont pas été utilisées dans ce tutoriel à des fins d'enseignement gtm.

Les options 3 et 4 permettent d'améliorer les performances de cette application. La les sections suivantes de cet atelier de programmation couvrent ces étapes. Comme tout codage essayez toujours d'écrire le code vous-même au lieu de le copier et de le coller.

N'importez que ce dont vous avez besoin

Quelques fichiers doivent être modifiés pour n'importer qu'une seule méthode à partir de lodash. Pour commencer, remplacez cette dépendance dans package.json:

"lodash": "^4.7.0",

par ceci:

"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 le mode 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 le panneau Network (Réseau). encore une fois.

Panneau &quot;Network&quot; (Réseau) affichant un bundle JavaScript de 15,2 Ko

Pour cette application, la taille du bundle a été multipliée par plus de quatre, avec très peu fonctionne, mais il reste encore beaucoup de place à améliorer.

Division du code

webpack est l'une des applications Open Source les bundlers de modules utilisés aujourd'hui. En bref, elle regroupe tous les modules JavaScript (comme ainsi que d'autres éléments) qui composent une application Web dans des fichiers statiques être lues par le navigateur.

Le bundle unique utilisé dans cette application peut être divisé en deux par blocs:

  • L'un responsable du code qui constitue notre route initiale
  • Un bloc secondaire qui contient notre code de tri

Avec les importations dynamiques, un fragment secondaire peut être chargé en différé. à la demande. Dans cette application, le code qui compose le bloc peut être chargé uniquement lorsque l'utilisateur appuie sur le bouton.

Commencez par supprimer l'importation de premier niveau 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'un proposition (actuellement à l'étape 3 du processus TC39) pour inclure la possibilité d'importer un module de manière dynamique. webpack prend déjà en charge ce processus et suit la même syntaxe que celle définie par la proposition.

import() renvoie une promesse et, une fois l'opération terminée, l'instance sélectionnée est fourni et est divisé en un fragment séparé. Une fois le module terminé, renvoyé, module.default est utilisé pour référencer la valeur par défaut exportation fournie par lodash. La promesse est enchaînée à un autre .then qui appelle une méthode sortInput pour trier les trois valeurs d'entrée. À la fin de 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 au niveau à la fin du fichier. Il doit s'agir d'une fonction qui renvoie une fonction qui utilise la méthode importée de lodash.sortBy. La fonction imbriquée peut alors 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 gardez un œil sur le réseau. dans le panneau. Seul un petit bundle initial est téléchargé dès que l'application charge.

Panneau &quot;Network&quot; (Réseau) affichant un bundle JavaScript de 2,7 Ko

Une fois que vous avez appuyé sur le bouton pour trier les nombres d'entrée, le bloc qui contient le code de tri est récupéré et exécuté.

Panneau &quot;Network&quot; affichant un bundle JavaScript de 2,7 Ko, suivi d&#39;un bundle JavaScript de 13,9 Ko

Remarquez comment les chiffres 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 paquet de votre application, ce qui peut entraîner le temps de chargement des pages est bien plus court. Cependant, il y a des choses importantes qui doivent à prendre en compte avant d'inclure cette optimisation dans votre application.

UI de chargement différé

Lors du chargement différé de modules de code spécifiques, il est important de réfléchir à la façon dont serait pour les utilisateurs ayant des connexions réseau plus faibles. Diviser et charger un très gros morceau de code lorsqu'un utilisateur soumet une action peut le rendre l'application semble avoir cessé de fonctionner. Envisagez donc d'afficher un indicateur de chargement.

Modules de nœuds tiers à chargement différé

Il ne s'agit pas toujours de la meilleure approche pour effectuer un chargement différé des dépendances tierces dans votre et cela dépend de l'endroit où vous les utilisez. En général, les systèmes les dépendances sont divisées en un bundle vendor distinct qui peut être mis en cache depuis elles ne sont pas mises à jour aussi souvent. Pour en savoir plus sur la façon dont les SplitChunksPlugin peut vous aider à y parvenir.

Chargement différé avec un framework JavaScript

De nombreux frameworks et bibliothèques populaires utilisant Webpack fournissent des abstractions pour faciliter le chargement différé plutôt que l'utilisation d'importations dynamiques application.

Bien qu'il soit utile de comprendre le fonctionnement des importations dynamiques, utilisez toujours la classe 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, utilisez les optimisations de navigateur telles que <link rel="preload">. ou <link rel="prefetch"> pour essayer de charger des modules critiques plus vite. webpack prend en charge ces deux suggestions grâce à l'utilisation de commentaires magiques dans l'importation. . Pour en savoir plus, consultez guide Précharger les fragments critiques.

Le chargement différé va au-delà du code

Les images peuvent constituer une part importante d'une application. Le chargement différé des éléments qui se trouvent en dessous de la ligne de flottaison ou en dehors de la fenêtre d'affichage de l'appareil, peuvent accélérer le chargement d'un site Web. Lue Pour en savoir plus à ce sujet, consultez Guide des tailles différées.