Réduire la portée et la complexité des calculs de style

JavaScript est souvent l'élément déclencheur de modifications visuelles. Parfois, ces modifications sont effectuées directement par des manipulations de style, et parfois par des calculs qui entraînent des changements visuels, tels que la recherche ou le tri de données. Les problèmes de performances sont souvent à l'origine des problèmes de performances dans le code JavaScript qui est chronométré ou dont l'exécution est de longue durée. Vous devez donc chercher à en minimiser l'impact lorsque cela est possible.

Calcul du style

Si vous modifiez le DOM en ajoutant et en supprimant des éléments, en modifiant des attributs, des classes ou en lisant des animations, le navigateur recalcule les styles des éléments et, dans de nombreux cas, la mise en page d'une partie ou de la totalité de la page. Ce processus est appelé calcul de style calculé.

Le navigateur commence à calculer les styles en créant un ensemble de sélecteurs correspondants pour déterminer les classes, les pseudo-sélecteurs et les ID qui s'appliquent à un élément donné. Ensuite, il traite les règles de style des sélecteurs correspondants et détermine les styles finaux de l'élément.

Délai de recalcul du style et latence d'interaction

Interaction to Next Paint (INP) est une métrique de performances d'exécution axée sur l'utilisateur qui évalue la réactivité globale d'une page aux entrées utilisateur. Il mesure la latence d'interaction entre le moment où l'utilisateur interagit avec la page et le moment où le navigateur affiche le frame suivant affichant les mises à jour visuelles correspondantes dans l'interface utilisateur.

Un élément important d'une interaction est le temps nécessaire pour peindre l'image suivante. Le travail de rendu effectué pour présenter le frame suivant comprend de nombreuses parties, y compris le calcul des styles de page qui ont lieu juste avant le travail de mise en page, de peinture et de composition. Cette page se concentre sur les coûts de calcul des styles, mais réduire n'importe quelle partie de la phase d'affichage liée à l'interaction réduit également sa latence totale, y compris pour les calculs de style.

Simplifiez vos sélecteurs

Simplifier les noms de vos sélecteurs peut vous aider à accélérer les calculs de style sur votre page. Les sélecteurs les plus simples référencent un élément en CSS avec un simple nom de classe:

.title {
  /* styles */
}

Toutefois, au fur et à mesure qu'un projet se développe, il a probablement besoin de CSS plus complexe, et vous pouvez vous retrouver avec des sélecteurs qui se présentent comme suit:

.box:nth-last-child(-n+1) .title {
  /* styles */
}

Pour déterminer 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 est l'élément enfant moins-ntième-plus-1 avec une classe de box ?". Trouver cette réponse peut prendre beaucoup de temps, en fonction du sélecteur utilisé ainsi que du navigateur en question. Pour simplifier ce processus, vous pouvez remplacer le sélecteur par un simple nom de classe:

.final-box-title {
  /* styles */
}

Ces noms de classes de remplacement peuvent sembler gênants, mais ils simplifient considérablement le travail du navigateur. Par exemple, dans la version précédente, pour que le navigateur sache qu'un élément est le dernier de son type, il doit d'abord tout savoir sur tous les autres éléments pour déterminer si des éléments ultérieurs peuvent être nth-last-child. Cela peut s'avérer beaucoup plus coûteux en calcul que la mise en correspondance d'un sélecteur avec un élément simplement parce que sa classe correspond.

Réduire le nombre d'éléments stylisés

Un autre élément à prendre en compte en termes de performances, et souvent plus important que la complexité du sélecteur, est la quantité de travail à effectuer lorsqu'un élément change.

En règle générale, le pire des cas de calcul du style des éléments calculés est le nombre d'éléments multipliés par le nombre de sélecteurs, car le navigateur doit vérifier chaque élément au moins une fois par rapport à chaque style pour voir s'il correspond.

Les calculs de style peuvent cibler directement quelques éléments au lieu d'invalider l'ensemble de la page. Dans les navigateurs récents, ce problème est généralement moins problématique, car il n'est pas nécessaire de vérifier tous les éléments qu'une modification peut affecter. En revanche, les navigateurs plus anciens ne sont pas toujours optimisés pour ce type de tâches. Dans la mesure du possible, vous devez réduire 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, procédez comme suit:

  1. Ouvrez les outils de développement.
  2. Accédez à l'onglet Performances.
  3. Cliquez sur Enregistrer.
  4. Interagissez avec la page.

Lorsque vous arrêtez l'enregistrement, l'image suivante s'affiche:

Outils de développement affichant des calculs de style
Rapport des outils de développement affichant des calculs de style.

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 les cadres sont rapides par le navigateur. Si le graphique de type "flamme" se stabilise en haut avec des barres rouges au-dessus, cela signifie que vous avez du travail qui entraîne des frames de longue durée.

Zoom sur une zone problématique dans les outils pour les développeurs Chrome dans le résumé d'activité du panneau "Performances" renseigné dans les outils pour les développeurs Chrome.
Frames à exécution longue dans le résumé de l'activité des outils de développement.

Les frames de longue durée lors d'une interaction, comme le défilement, valent la peine d'être examinés de plus près. Si vous voyez un grand bloc violet, faites un zoom avant sur l'activité et sélectionnez un travail intitulé Recalculate Style (Recalculer le style) pour obtenir plus d'informations sur les tâches de recalcul de style potentiellement coûteuses.

obtenir les détails des calculs de style de longue durée, y compris des informations essentielles telles que la quantité d'éléments affectés par le travail de recalcul des styles ;
Recalcul de style de longue durée prenant un peu plus de 25 ms dans le résumé des outils de développement.

Cliquez sur l'événement pour afficher la pile d'appel correspondante. Si le travail de rendu a été causé par une interaction de l'utilisateur, il appelle le code JavaScript ayant déclenché le changement de style. Il indique également le nombre d'éléments affectés par la modification (un peu plus de 900 éléments dans ce cas) et la durée du calcul du style. Vous pouvez utiliser ces informations pour essayer de trouver un correctif 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 afin d'obtenir des avantages en termes de performances. BEM recommande que tout ait une seule classe et, lorsque vous avez besoin d'une hiérarchie, cette hiérarchie est également intégrée dans le nom de la classe:

.list {
  /* Styles */
}

.list__list-item {
  /* Styles */
}

Si vous avez besoin d'un modificateur, comme dans l'exemple du dernier enfant, vous pouvez l'ajouter comme suit:

.list__list-item--last-child {
  /* Styles */
}

L'outil BEM constitue un bon point de départ pour organiser votre CSS, à la fois du point de vue de la structure et en raison de la simplification de la recherche de styles dont il fait la promotion.

Si vous n'aimez pas le BEM, il existe d'autres façons d'aborder votre CSS. Toutefois, vous devez évaluer ses performances et son ergonomie avant de commencer.

Ressources

Image principale de Unsplash, de Markus Spiske.