Optimiser le code JavaScript tiers

Les scripts tiers ont un impact sur les performances. Il est donc important de les auditer régulièrement et d'utiliser des techniques de chargement efficaces. Cet atelier de programmation vous explique comment optimiser le chargement des ressources tierces. Il aborde les techniques suivantes:

  • Reporter le chargement du script

  • Ressources non critiques à chargement différé

  • Préconnexion aux origines requises

L'application exemple incluse comporte une page Web simple avec trois fonctionnalités provenant de sources tierces:

  • Intégration d'une vidéo

  • Bibliothèque de visualisation de données permettant d'afficher un graphique linéaire

  • Un widget de partage sur les réseaux sociaux

<ph type="x-smartling-placeholder">
</ph> Capture d&#39;écran de la page avec les ressources tierces mises en évidence
Ressources tierces dans l'application exemple

Vous commencerez par mesurer les performances de l'application, puis vous appliquerez chaque technique pour améliorer différents aspects des performances de l'application.

Évaluer les performances

Commencez par ouvrir l'application exemple en plein écran:

  1. Cliquez sur Remix to Edit (Remixer pour modifier) pour pouvoir modifier le projet.
  2. Pour prévisualiser le site, appuyez sur Afficher l'application. Appuyez ensuite sur Plein écran plein écran

Effectuez un audit de performances Lighthouse sur la page pour établir des performances de référence:

  1. Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir les outils de développement.
  2. Cliquez sur l'onglet Lighthouse.
  3. Cliquez sur Mobile.
  4. Cochez la case Performances. (Vous pouvez décocher les autres cases dans la section "Audits".)
  5. Cliquez sur Simulée de 3G rapide, Ralentissement du processeur 4x.
  6. Cochez la case Vider l'espace de stockage.
  7. Cliquez sur Exécuter des audits.

Lorsque vous effectuez un audit sur votre machine, les résultats exacts peuvent varier, mais vous devez noter que la durée First Contentful Paint (FCP) est assez élevée et que Lighthouse suggère deux pistes à explorer: Éliminer les ressources bloquant l'affichage et Se préconnecter aux origines requises. (Même si toutes les métriques sont affichées en vert, les optimisations permettront quand même d'obtenir des améliorations.)

Capture d&#39;écran de l&#39;audit Lighthouse montrant un FCP de 2,4 secondes et deux opportunités: élimination des ressources qui bloquent l&#39;affichage et préconnexion aux origines requises.

Reporter le code JavaScript tiers

L'audit Éliminer les ressources bloquant l'affichage indique que vous pouvez gagner du temps en différant un script provenant de d3js.org:

Capture d&#39;écran de l&#39;audit &quot;Éliminer les ressources bloquant l&#39;affichage&quot; avec le script d3.v3.min.js mis en évidence.

D3.js est une bibliothèque JavaScript permettant de créer des visualisations de données. Le fichier script.js de l'application exemple utilise les fonctions utilitaires D3 pour créer le graphique en courbes SVG et l'ajouter à la page. L'ordre des opérations ici est important: script.js doit s'exécuter après l'analyse du document et le chargement de la bibliothèque D3. C'est pourquoi il est inclus juste avant la balise de fermeture </body> dans index.html.

Cependant, le script D3 est inclus dans le fichier <head> de la page, ce qui bloque l'analyse du reste du document:

Capture d&#39;écran du fichier index.html avec la balise de script en surbrillance dans l&#39;en-tête.

Deux attributs magiques peuvent débloquer l'analyseur lorsqu'il est ajouté à la balise de script:

  • async garantit que les scripts se téléchargent en arrière-plan et s'exécutent à la première occasion après la fin du téléchargement.

  • defer garantit que les scripts se téléchargent en arrière-plan et s'exécutent une fois l'analyse terminée.

Étant donné que ce graphique n'est pas vraiment essentiel à l'ensemble de la page et qu'il se trouvera probablement en dessous de la ligne de flottaison, utilisez defer pour vous assurer qu'il n'y a pas de blocage de l'analyseur.

Étape 1: Chargez le script de manière asynchrone avec l'attribut defer

À la ligne 17 de index.html, ajoutez l'attribut defer à l'élément <script>:

<script src="https://d3js.org/d3.v3.min.js" defer></script>

Étape 2: Vérifiez le bon ordre des opérations

Maintenant que D3 est différé, script.js s'exécutera avant que D3 ne soit prêt, ce qui génère une erreur.

Les scripts dotés de l'attribut defer s'exécutent dans l'ordre dans lequel ils ont été spécifiés. Pour vous assurer que script.js s'exécute une fois que D3 est prêt, ajoutez-y defer et déplacez-le jusqu'à la <head> du document, juste après l'élément <script> de D3. Désormais, il ne bloque plus l'analyseur, et le téléchargement démarre plus tôt.

<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>

Ressources tierces à chargement différé

Toutes les ressources situées en dessous de la ligne de flottaison sont de bonnes candidates au chargement différé.

L'application exemple intègre une vidéo YouTube dans un iFrame. Pour connaître le nombre de demandes générées par la page et celles provenant de l'iFrame YouTube intégré:

  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. Sélectionnez 3G rapide dans le menu déroulant Limitation.
  6. Actualisez la page.

Capture d&#39;écran du panneau DevTools Network.

Le panneau Network (Réseau) indique que la page a effectué 28 requêtes au total et transféré près de 1 Mo de ressources compressées.

Pour identifier les demandes envoyées par le iframe YouTube, recherchez l'ID vidéo 6lfaiXM6waw dans la colonne Initiator (Initiateur). Pour regrouper toutes les requêtes par domaine:

  • Dans le panneau Réseau, effectuez un clic droit sur le titre d'une colonne.

  • Dans le menu déroulant, sélectionnez la colonne Domains (Domaines).

  • Pour trier les requêtes par domaine, cliquez sur le titre de la colonne Domains (Domaines).

Le nouveau tri indique la présence de requêtes supplémentaires auprès des domaines Google. Au total, l'iFrame YouTube génère 14 demandes de scripts, de feuilles de style, d'images et de polices. Mais à moins que les utilisateurs ne fassent défiler la page pour lire la vidéo, ils n'ont pas vraiment besoin de tous ces éléments.

En attendant le chargement différé de la vidéo jusqu'à ce qu'un utilisateur fasse défiler la page jusqu'à cette section, vous réduisez le nombre de demandes initiales de la page. Cette approche évite aux utilisateurs et accélère le chargement initial.

Pour implémenter le chargement différé, vous pouvez utiliser Intersection Observer, une API de navigateur qui vous avertit lorsqu'un élément arrive dans la fenêtre d'affichage du navigateur ou en sort.

Étape 1: Empêchez le chargement initial de la vidéo

Pour effectuer un chargement différé de l'iFrame vidéo, vous devez d'abord empêcher son chargement comme d'habitude. Pour ce faire, remplacez l'attribut src par l'attribut data-src afin de spécifier l'URL de la vidéo:

<iframe width="560" height="315" data-src="https://www.youtube.com/embed/lS9D6w1GzGY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

data-src est un attribut de données qui vous permet de stocker des informations supplémentaires sur des éléments HTML standards. Vous pouvez nommer un attribut de données comme vous le souhaitez, à condition qu'il commence par "data-".

Un iFrame sans src ne se charge tout simplement pas.

Étape 2: Utilisez Intersection Observer pour charger la vidéo en différé

Pour charger la vidéo lorsqu'un utilisateur la fait défiler, vous devez savoir à quel moment cela se produit. C'est là qu'intervient l'API Intersection Observer. L'API Intersection Observer vous permet d'enregistrer une fonction de rappel qui s'exécute chaque fois qu'un élément que vous souhaitez suivre entre dans la fenêtre d'affichage ou en sort.

Pour commencer, créez un fichier et nommez-le lazy-load.js:

  • Cliquez sur Nouveau fichier et donnez-lui un nom.
  • Cliquez sur Ajouter ce fichier.

Ajoutez le tag de script à l'en-tête de votre document:

 <script src="/lazy-load.js" defer></script>

Dans lazy-load.js, créez un IntersectionObserver et transmettez-lui une fonction de rappel à exécuter:

// create a new Intersection Observer
let observer = new IntersectionObserver(callback);

Attribuez maintenant à observer un élément cible à regarder (l'iFrame vidéo dans ce cas) en le transmettant en tant qu'argument dans la méthode observe:

// the element that you want to watch
const element = document.querySelector('iframe');

// register the element with the observe method
observer.observe(element);

callback reçoit une liste d'objets IntersectionObserverEntry et l'objet IntersectionObserver lui-même. Chaque entrée contient un élément target et des propriétés qui décrivent ses dimensions, sa position, l'heure d'entrée dans la fenêtre d'affichage, etc. L'une des propriétés de IntersectionObserverEntry est isIntersecting, une valeur booléenne égale à true lorsque l'élément entre dans la fenêtre d'affichage.

Dans cet exemple, target correspond à iframe. isIntersecting est égal à true lorsque target entre dans la fenêtre d'affichage. Pour voir comment cela fonctionne, remplacez callback par la fonction suivante:

let observer = new IntersectionObserver(callback);
let observer = new IntersectionObserver(function(entries, observer) {
    entries.forEach(entry => {
      console.log(entry.target);
      console.log(entry.isIntersecting);
    });
  });
  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 Console.

Essayez de faire défiler l'écran vers le haut et vers le bas. La valeur de isIntersecting doit changer et l'élément cible doit être enregistré dans la console.

Pour charger la vidéo lorsque l'utilisateur fait défiler la page jusqu'à sa position, utilisez isIntersecting comme condition pour exécuter une fonction loadElement, qui récupère la valeur de la data-src de l'élément iframe et la définit comme attribut src de l'élément iframe. Ce remplacement déclenche le chargement de la vidéo. Ensuite, une fois la vidéo chargée, appelez la méthode unobserve sur observer pour arrêter de regarder l'élément cible:

let observer = new IntersectionObserver(function (entries, observer) {
  entries.forEach(entry => {
    console.log(entry.target);
    console.log(entry.isIntersecting);
  });
});
    if (entry.isIntersecting) {
      // do this when the element enters the viewport
      loadElement(entry.target);
      // stop watching
      observer.unobserve(entry.target);
    }
  });
});

function loadElement(element) {
  const src = element.getAttribute('data-src');
  element.src = src;
}

Étape 3: Réévaluer les performances

Pour voir comment la taille et le nombre de ressources ont changé, ouvrez le panneau Network (Réseau) des outils de développement, puis actualisez de nouveau la page. Le panneau Network (Réseau) indique que la page a effectué 14 requêtes et que sa taille est limitée à 260 Ko. C'est une amélioration significative !

Maintenant, faites défiler la page vers le bas et gardez un œil sur le panneau Network (Réseau). Lorsque vous arrivez à la vidéo, la page doit déclencher des requêtes supplémentaires.

Se préconnecter aux origines requises

Vous avez différé le code JavaScript non critique et le chargement différé des requêtes YouTube. Il est donc temps d'optimiser le contenu tiers restant.

L'ajout de l'attribut rel=preconnect à un lien indique au navigateur d'établir une connexion avec un domaine avant que la requête pour cette ressource ne soit effectuée. Il est préférable d'utiliser cet attribut sur les origines qui fournissent les ressources dont vous êtes certain que la page a besoin.

L'audit Lighthouse que vous avez effectué à la première étape était suggéré dans Préconnexion aux origines requises. Vous pouvez gagner environ 400 ms en établissant les premières connexions à statiquexx.facebook.com et youtube.com:

Préconnectez-vous à l&#39;audit des origines requises avec le domaine &quot;staticxx.facebook.com&quot; mis en évidence.

Étant donné que la vidéo YouTube est à présent chargée en différé, seul le site statiquexx.facebook.com est la source du widget de partage sur les réseaux sociaux. Pour établir une connexion anticipée à ce domaine, il suffit d'ajouter une balise <link> au fichier <head> du document:

  <link rel="preconnect" href="https://staticxx.facebook.com">

Réévaluer les performances

Voici l'état de la page après optimisation. Suivez les étapes de la section Mesurer les performances de l'atelier de programmation pour exécuter un autre audit Lighthouse.

Audit Lighthouse indiquant un FCP d&#39;une seconde et un score de performance de 99.