Optimisation des actifs JavaScript pour la vitesse de la page
Publié: 2020-05-05L'exemple ci-dessous provient d'un grand site Web d'actualités complexe. Ils perdent du trafic organique depuis des années. Leur timing d'événement DOMContentLoaded est 2615.2 MS. Vous pensez peut-être que leur taille DOM est extrêmement énorme, mais non…
C'est presque la même chose que ce que Google recommande, et seuls 1230 nœuds HTML existent dans ce document.
Vous pouvez calculer la durée et le processus de votre événement domContentLoaded et le comparer à vos concurrents à l'aide de DevTools.
L'examen de cet exemple montre que la taille du DOM n'est pas nécessairement le point critique. Ici, le principal problème est l' ordre des ressources : les parties bleues dans "Main Tab" sont destinées à l'analyse HTML. Cependant, ce site Web interrompt le navigateur avec le rendu JavaScript avant la fin du processus d'analyse HTML.
(Vous pouvez également utiliser la section Call Tree pour vous aider à trouver des erreurs similaires pour votre équipe informatique.)
Cet exemple illustre clairement l'importance d'optimiser les actifs JavaScript et ce qui peut mal tourner lorsque vous négligez JavaScript dans les optimisations de vitesse de votre page.
Ceci est le troisième d'une série de quatre articles. Pour mieux comprendre cet article, vous pouvez lire les deux premiers articles de la série :
- Le rendu Javascript et la vitesse de la page sont étroitement liés à la façon dont le moteur de rendu d'un navigateur crée une page Web.
- Vous devez également comprendre les mesures avancées de vitesse de page avant d'entrer dans cet article.
Je vais utiliser quelques exemples des deux premiers articles pour aider à fournir un contexte dans celui-ci.
Qu'est-ce que le rendu Javascript et comment affecte-t-il la vitesse de votre page ?
Le rendu Javascript est la dernière section de chargement de page qui peut modifier de manière interactive la structure créée à l'aide du DOM et du CSSOM. Tout élément de page peut être modifié dans un format déclenchable par l'utilisateur ou affiché normalement. Tout élément avec une propriété display:none qui n'est pas accessible par l'arbre de rendu peut être rendu visible avec JavaScript ou injecté via différents éléments HTML dans le DOM.
JavaScript interrompt le DOM et le CSSOM car il modifie le DOM et le CSSOM au moment où ils sont lus par le navigateur. Par conséquent, pour éviter qu'il n'ait un impact négatif sur le temps et la vitesse de chargement des pages, il est nécessaire d'examiner la relation entre le rendu DOM, CSSOM et JavaScript.
Ci-dessus, un exemple d'arbre de rendu. Tous les extraits de code imbriqués dans les nœuds CSSOM et HTML ont des équivalents sémantiques dans l'arborescence de rendu. Si vous regardez attentivement, vous remarquerez que le nœud HTML "Bouton d'action" n'est pas dans l'arborescence de rendu. La raison principale en est "display: none ;" propriété CSS. En raison de cette commande d'invisibilité, il n'est pas inclus dans l'arborescence de rendu. Pour voir comment les éléments de cet arbre ont été construits, vous pouvez lire le premier article de cette série.
Si vous avez de nombreux éléments de page qui n'apparaîtront pas au premier chargement car ils dépendent du comportement de l'utilisateur, dans l'ordre de chargement des ressources, vous devrez séparer ces éléments et les mettre dans la dernière ligne. L'utilisation d'un DOM fantôme ou d'un DOM virtuel sont de meilleures options à ce stade.
Attributs différés et asynchrones pour les ressources JavaScript
Si vous mettez vos fichiers JS dans la section et si vous n'utilisez pas les attributs 'defer' ou 'async', cela retardera probablement votre temps DOMContentLoaded. Pour éviter cette situation, nous pouvons utiliser ces deux attributs. Defer consiste à retarder le processus de chargement d'un fichier JS tandis que 'Async' consiste à charger JS et d'autres sources de manière parallèle. Les deux ont des avantages et des inconvénients. Nous ne parlerons ici que des principaux.
- Si vous utilisez defer sur un fichier JS principal, vous ne verrez probablement pas ses effets "initiateur" tant qu'il n'est pas installé.
- Si vous utilisez trop de report, vous risquez de provoquer un goulot d'étranglement du processeur à la fin du chargement de la page.
Depuis la rédaction de cet article, la mise à jour Chrome 80 a été publiée. Dans la colonne Initiateur, il est maintenant beaucoup plus facile de voir quelle ressource est appelée par quelle ressource. Par exemple, vous pouvez voir une image ou un fichier CSS appelé par JS. Si vous faites défiler les ressources en maintenant la touche Maj enfoncée, vous verrez également quelle ressource ne peut pas être utilisée sans charger d'autres ressources.
Défilement en maintenant la touche Maj enfoncée : la couleur rouge indique la ressource conditionnelle pour la ressource surlignée en vert.
Vous pouvez également utiliser la nouvelle section Initiateur de Chrome pour un ordre de chargement des ressources, un initiateur et un examen des priorités plus détaillés. Cela vous permet de détecter des chaînes d'appels JS extrêmement longues et coûteuses comme celle ci-dessous.
Un exemple d'une chaîne d'appels JS longue et coûteuse à partir d'un même site. Au-dessus de la ressource sélectionnée se trouvent ses initiateurs. La partie suivante montre les ressources initiées par la ressource sélectionnée.
- Les fichiers JS différés sont téléchargés après l'événement domInteractive, vous devez donc les choisir en fonction de vos fichiers CSS et images.
- Si vous différez certains fichiers JS tiers de suivi des utilisateurs, vous ne pourrez peut-être pas suivre certains comportements des utilisateurs.
- Defer ne bloque généralement pas le processus DOM, contrairement à Async. Les fichiers JS avec des attributs asynchrones sont téléchargés par le navigateur lors de l'analyse HTML et du traitement CSSOM.
- Si vous utilisez trop l'attribut async, vous créerez probablement un goulot d'étranglement dans le traitement du processeur et vous ralentirez également vos processus DOM et CSSOM. Vous devez choisir avec soin ce qu'il faut différer ou asynchroniser.
Voici un exemple de schéma pour les attributs asynchrones et différés. Le premier est chargé avant domContentLoaded sans fractionner l'analyse HTML lors de la récupération. Dans le second cas, le fichier JS récupéré n'est pas exécuté avant la fin de l'analyse HTML.
Suggestions et astuces pour le rendu et les performances de Javascript
Avant de passer aux exemples pratiques, voici quelques suggestions pour améliorer les performances de rendu JavaScript. Cela peut également aider à mieux comprendre la vitesse des pages et le fonctionnement d'un navigateur.
N'utilisez pas de variables inutiles.
Si vous êtes SEO, vous remarquerez peut-être des variables inutiles ou inutilisées dans un fichier JavaScript. De nombreux outils peuvent être utilisés pour détecter ce type d'erreur. Vous trouverez ci-dessous deux exemples de base pour les variables inutilisées et inutiles.
var carName= marque+ ” ” + année ;
document.getElementById("demo").innerHTML = carName;
Ici, la variable « carName » est inutile. Vous pouvez suggérer la modification suivante :
document.getElementById(“démo”).innerHTML = marque+ ” ” + année
Ou alors:
[a, b, c, d, e].forEach(fonction (valeur, index) {
console.log(index);
});
Ici, le paramètre "valeur" n'est pas nécessaire, car il n'est pas utilisé. Vous pouvez le supprimer :
[a, b, c, d, e].forEach(fonction (indice) {
console.log(index);
});
Sur le côté droit, vous pouvez voir des temps de connexion plus longs (lignes blanches) et les fichiers CSS et JS sont chargés dans un ordre asymétrique grâce aux Javascripts "async".
Sur le côté gauche, les temps de connexion sont plus courts et les fichiers CSS et JS ne sont pas mélangés car chaque source est chargée en lignes. Les attributs asynchrones peuvent réduire votre indice de vitesse car ils peuvent prolonger le temps TBT, vous devez donc effectuer une enquête et le signaler à votre équipe de développeurs pour les fichiers JS de suivi des performances à partir de l'onglet performances, ou vous pouvez exécuter des expériences par vous-même.
Utiliser des outils pour les tâches difficiles
Pour un débutant en code, trouver des variables inutiles ou inutilisées peut être difficile. Vous voudrez peut-être utiliser certains outils pour ces tâches, tels que les packages Chrome DevTools ou Node.js comme Unused (Kami/node-unused : un module qui signale des variables définies mais inutilisées dans votre code. ou pour plus de variables inutilisées). Si vous trouvez ne serait-ce que de petites erreurs, je pense que votre équipe informatique vous écoutera pour améliorer vos fichiers JavaScript.
Utilisation du rapport de couverture de Chrome DevTools pour trouver le code JavaScript inutilisé
Le rapport de couverture de Chrome DevTools affiche des extraits de code JavaScript inutilisés, mais ce n'est pas très pratique. Vous pouvez penser que vous pouvez supprimer toutes les parties rouges du code mais ce n'est pas le cas… Au lieu de cela, vous devriez trouver des fonctions ou des variables totalement inutilisées pour un grand nombre de pages de catégories. De cette façon, votre équipe de développeurs peut être convaincue d'utiliser un processus TreeShaking.
TreeShaking signifie supprimer le code mort des fichiers. Je recommande d'apprendre à utiliser des variables JS inutilisées et des packages de recherche de fonctions afin de gagner du temps.
Une taille DOM plus petite aidera également avec le rendu JavaScript. Chaque commande (getElementsByTagName) analysera votre DOM. Une taille DOM plus petite nécessitera moins de ressources de votre navigateur et du processeur/réseau de votre appareil lors du rendu de JavaScript.
Avec la nouvelle mise à jour de Chrome 80, le rapport de couverture a également subi un changement. Ils ont ajouté des choix facultatifs par fonction et par bloc. Par bloc est la valeur par défaut ici.
Si vous choisissez Par fonction, vous verrez une grande différence dans votre rapport. La raison principale de cette situation est que la vue Par fonction vérifie si toute la fonction est utilisée ou non. Si 95 % de la fonction est utilisée, l'option Par fonction la définira comme code inutilisé car 5 % du code n'est pas utilisé, bien que la majeure partie de la fonction soit utilisée.
Compressez, Minify ou Uglify vos fichiers JS.
Ceci peut être fait de deux façons. Tout d'abord, supprimez les espaces et les commentaires inutiles. Deuxièmement, utilisez des opérateurs JavaScript améliorés pour vos fichiers JS et modifiez les noms, les variables et les fonctions avec des technologies prêtes à l'emploi.
Vous devez connaître les fonctions fléchées pour ce type de compression. Par exemple, au lieu de cet exemple de 84 caractères :
fonction flèche Islev (a, b) {
console.log (a + b);
}
arrowFonksiyon (5, 6);
Vous pouvez le compresser à seulement 50 caractères avec les fonctions fléchées =>
const ab = (a, b) => b + a ;
console.log (ab (5, 6));
Une autre méthode de raccourcissement/compression est valide pour les instructions If. Au lieu de cet extrait de code de 63 caractères :
si (a<b) {
console.log(ab);
}
autre {
console.log(a+b);
Vous pouvez utiliser celui avec 43 caractères ci-dessous :
(a<b) ? console.log(ab) : console.log(a+b);
Vous pouvez également suggérer à votre équipe informatique d'utiliser les signes $ et _ pour la compression. La plupart des fichiers JavaScript fonctionnent pour réinterpréter DOM. Pour cela, vous pouvez voir beaucoup de document.getElementById(x); extraits de code dans les fichiers. Vous pouvez utiliser un signe $ pour cette tâche. Cela vous évitera un énorme tas de taille inutile.
La plupart des bibliothèques JavaScript utilisent $ par défaut pour la définition des fonctions, mais pas toutes, car $ est aussi un caractère alphabétique.
Dans cette situation, vous pouvez suggérer à votre équipe informatique d'utiliser :
fonction $(x) {return document.getElementById(x);} .
Utiliser un type de rendu approprié
JavaScript et types de rendu de page Web en termes de compatibilité SEO.
L'hydratation SSR signifie que certains des composants JS seront rendus à l'aide du rendu côté client. Il est utile pour FP et FMP, mais il peut y avoir des inconvénients pour les scores TTI et Speed Index.
Source de l'image : Notprovided.eu
Meilleures pratiques de codage pour les performances de rendu JavaScript
- Une autre contribution importante à la compression viendra de l'utilisation de "_". Vous pouvez utiliser « underscore.js » pour améliorer les formats et les fonctions d'écriture JavaScript. De cette façon, vous créerez des fichiers JS plus petits tout en manipulant des listes et des collections avec des fonctions JS plus courtes sans fonctions JS intégrées.
- L'utilisation de nombreux changements de variables longs et épuisants et la pollution des variables globales sont également des sources de ralentissement du rendu. Vous devez déterminer les choix de portée générale de vos fonctions et les types de variables globales/variables longues. L'utilisation de variables locales avec 'Let' est meilleure pour le rendu. En raison des variables locales, les navigateurs n'auditeront pas les autres variables de fonctions globales pour le prochain changement.
Pour simuler un examen des performances plus réaliste, par exemple, ce que vous pourriez voir sur les téléphones mobiles bas de gamme, vous devez utiliser les préférences de limitation du processeur et de connexion 3G rapide/lente dans Chrome DevTools.
Source de l'image : Addy Osmani
- L'utilisation de fonctions JS plus petites et de chaînes de variables améliorera vos performances de rendu. De plus, il est préférable d'utiliser le sélecteur "ceci" au lieu du sélecteur "avec". "Ce" sélecteur en Javascript est un code de fonctionnement local contrairement à "avec", la même logique avec let et var est également valable ici.
- Si vous utilisez vos instructions dans des extraits de code de boucle For, cela ralentira également un peu votre vitesse de rendu. Parce que votre instruction de fonction parcourra chaque élément de la boucle. Vous pouvez simplement créer une nouvelle variable pour les éléments de boucle et vous pouvez appeler ces éléments avec une fonction qui est en dehors de la boucle For.
- Si vous souhaitez accéder plusieurs fois à un élément HTML, vous pouvez lui créer une variable et l'appeler avec les fonctions souhaitées. Atteindre un élément HTML avec JavaScript n'est pas un processus rapide. Vous pourriez simplement créer plus de charge pour votre navigateur.
Une autre façon d'améliorer les performances de rendu Javascript est le rendu trisomorphe via les Service Workers. Vous pouvez placer certains de vos fichiers JS dans la mémoire du navigateur du client pour les sessions futures. De cette façon, vous pouvez faire fonctionner votre site Web hors ligne.
Vous pouvez trouver une démonstration simple pour une meilleure compréhension et une chance de pratiquer avec les travailleurs de service ici
Ligoter : comment l'optimisation de JavaScript et de la vitesse des pages affecte le référencement
Pour empêcher les actifs JavaScript de saboter la vitesse de votre page, nous avons vu comment Defer et Async peuvent faire une énorme différence. Nous avons également examiné quelques-unes des stratégies de "débogage" et des conseils de codage qui peuvent vous aider à améliorer la vitesse de vos pages avec des ressources JavaScript.
Maintenant que nous avons vu comment les navigateurs créent des pages Web, comment la vitesse des pages est mesurée et affectée, et le rôle que l'optimisation de JavaScript joue dans le temps de chargement des pages, le prochain article montrera comment l'ordre de chargement des ressources affecte la vitesse des pages et le budget d'exploration.
Si vous souhaitez revoir les articles précédents de cette série de quatre articles, vous pouvez les trouver ici :
- "Comment un navigateur crée-t-il une page Web"
- "Métriques de vitesse de page avancées".