JavaScript est souvent à l'origine de modifications visuelles. Parfois, cela se fait directement grâce à des manipulations de style, et parfois ce sont des calculs qui entraînent des changements visuels, comme la recherche ou le tri de certaines données. Les problèmes de performances sont souvent à l'origine des problèmes de performances du code JavaScript qui sont incorrects ou dont l'exécution est de longue durée. Vous devez donc chercher à en minimiser l'impact lorsque cela est possible.
Le fait de modifier le DOM (par exemple, en ajoutant et en supprimant des éléments, en changeant des attributs, des classes ou via une animation) entraîne le recalcul des styles des éléments et, dans de nombreux cas, la mise en page (ou la remise en page) de la page ou de certaines parties de celle-ci. Ce processus est appelé calcul de style calculé.
La première partie des styles de calcul consiste à créer un ensemble de sélecteurs correspondants, c'est-à-dire essentiellement le navigateur qui détermine les classes, les pseudo-sélecteurs et les ID qui s'appliquent à un élément donné.
La deuxième partie du processus consiste à prendre toutes les règles de style des sélecteurs correspondants et à déterminer les styles finaux de l'élément.
Résumé
- Comment la réduction des coûts de calcul des styles peut réduire la latence des interactions.
- Réduisez la complexité de vos sélecteurs en utilisant une méthodologie axée sur les classes (BEM, par exemple).
- Réduisez le nombre d'éléments sur lesquels le calcul de style doit être calculé.
Délai de recalcul du style et latence d'interaction
INP (Interaction to Next Paint) est une métrique de performances d'exécution axée sur l'utilisateur. Elle évalue la réactivité globale d'une page aux entrées utilisateur. Lorsque la latence d'interaction est évaluée par cette métrique, elle mesure le temps qui s'écoule entre le moment où l'utilisateur interagit avec la page et le moment où le navigateur affiche le frame suivant, montrant les modifications visuelles correspondantes apportées à l'interface utilisateur.
Une composante importante d'une interaction est le temps nécessaire pour peindre le prochain frame. Le travail de rendu effectué pour présenter le cadre suivant comporte de nombreuses étapes, y compris le calcul des styles de page qui ont lieu juste avant le travail de mise en page, de peinture et de composition. Bien que cet article se concentre uniquement sur les coûts de calcul des styles, il est important de souligner que la réduction de toute partie de la phase de rendu inhérente à l'interaction réduira la latence totale, y compris le calcul des styles.
Simplifiez vos sélecteurs
Dans le cas le plus simple, vous pouvez référencer un élément dans votre code CSS à l'aide d'une seule classe:
.title {
/* styles */
}
Toutefois, au fur et à mesure qu'un projet se développe, il est probable que le code CSS soit plus complexe, ce qui vous permettra peut-être d'obtenir des sélecteurs qui se présentent comme suit:
.box:nth-last-child(-n+1) .title {
/* styles */
}
Pour savoir comment ces styles s'appliquent à la page, le navigateur doit demander : "S'agit-il d'un élément avec une classe de title
dont le parent se trouve être le nième enfant moins 1 élément avec une classe de box
?". Trouver cela peut prendre beaucoup de temps, selon le sélecteur utilisé et le navigateur en question. À la place, le comportement souhaité du sélecteur pourrait être remplacé par une classe:
.final-box-title {
/* styles */
}
Vous pouvez contester le nom de la classe, mais la tâche devient beaucoup plus simple pour le navigateur. Dans la version précédente, pour savoir, par exemple, que l'élément est le dernier de son type, le navigateur doit d'abord tout savoir sur tous les autres éléments et déterminer s'il s'agit d'éléments qui suivent, comme la nth-last-child
, ce qui est potentiellement plus coûteux que de simplement faire correspondre le sélecteur à l'élément, car sa classe correspond.
Réduire le nombre d'éléments stylisés
Un autre élément à prendre en compte en termes de performances, qui est généralement le facteur le plus important pour de nombreuses mises à jour de style, est le volume de travail à effectuer lorsqu'un élément change.
En règle générale, le coût le plus faible pour calculer le style des éléments calculé est le nombre d'éléments multipliés par le nombre de sélecteurs, car chaque élément doit être vérifié au moins une fois par rapport à chaque style pour voir s'il correspond.
Les calculs de style peuvent souvent cibler directement quelques éléments au lieu d'invalider la page dans son ensemble. Dans les navigateurs récents, ce problème est généralement moins problématique, car il n'est pas nécessaire que le navigateur vérifie tous les éléments potentiellement concernés par une modification. En revanche, les navigateurs plus anciens ne sont pas nécessairement optimisés pour ce type de tâches. Lorsque c'est possible, réduisez le nombre d'éléments invalidés.
Mesurer le coût de recalcul des styles
Pour mesurer le coût des recalculs de style, vous pouvez utiliser le panneau des performances dans les outils pour les développeurs Chrome. Pour commencer, ouvrez les outils de développement, accédez à l'onglet Performances, cliquez sur "Enregistrer", puis interagissez avec la page. Lorsque vous arrêtez l'enregistrement, un écran semblable à l'image ci-dessous s'affiche:
La bande supérieure est un graphique de flammes miniature qui représente également le nombre d'images par seconde. Plus l'activité est proche du bas de la bande, plus le navigateur affiche les images rapidement. Si le graphique de type "flamme" se stabilise en haut avec des bandes rouges au-dessus, cela signifie que votre travail entraîne des images de longue durée.
Si votre frame s'affiche depuis longtemps lors d'une interaction, comme un défilement, il doit être examiné de plus près. Si vous disposez d'un grand bloc violet, faites un zoom avant sur l'activité et sélectionnez un devoir intitulé Recalculer Style (Recalculer le style) pour obtenir plus d'informations sur les travaux de recalcul de style potentiellement coûteux.
Dans cette capture, il y a un travail de recalcul de style de longue durée qui prend un peu plus de 25 ms.
Si vous cliquez sur l'événement lui-même, vous recevez une pile d'appel. Si le rendu du rendu est dû à une interaction de l'utilisateur, l'emplacement dans le code JavaScript qui est à l'origine du changement de style sera indiqué. En outre, vous obtenez le nombre d'éléments affectés par la modification (un peu plus de 900 éléments dans le cas présent) et le temps nécessaire pour calculer le style. Vous pouvez utiliser ces informations pour essayer de trouver une solution dans votre code.
Utiliser les blocs, l'élément et le modificateur
Des approches de codage telles que BEM (bloc, élément, modificateur) sont intégrées dans le sélecteur, qui correspondent aux avantages de performances ci-dessus, car elles recommandent que tous les éléments aient une seule classe et, si vous avez besoin d'une hiérarchie, le nom de la classe est également intégré:
.list {
/* Styles */
}
.list__list-item {
/* Styles */
}
Si vous avez besoin d'un modificateur, comme dans l'exemple ci-dessus, où nous voulons faire quelque chose de spécial pour le dernier enfant, vous pouvez l'ajouter comme suit:
.list__list-item--last-child {
/* Styles */
}
Si vous cherchez un bon moyen d'organiser votre CSS, l'outil BEM constitue un bon point de départ, d'un point de vue structurel, mais aussi en raison des simplifications de la recherche de style dont la méthodologie met en avant.
Si vous n'aimez pas le BEM, il existe d'autres façons d'aborder votre CSS. Toutefois, les considérations relatives aux performances doivent être évaluées parallèlement à l'ergonomie de cette approche.
Ressources
Image principale de Unsplash, de Markus Spiske.