Le cout en performance des animations CSS peuvent varier d'une propriété à une autre, et animer des propriétés couteuses peut résulter en un ralentissement/blocage du navigateur (jank) tandis que le navigateur se débat pour obtenir un frame rate fluide.
Le Frame rate et la Chronologie peuvent fournir des renseignements sur les opérations que fait le navigateur lors d'une animation CSS, dans le but d'aider à diagnostiquer les problèmes de performances.
Avec les animations CSS, il est possible de spécifier un nombre keyframes, chacune de celle-ci utilisent du CSS pour définir l'apparence d'un élément à un moment donné de l'animation. Le navigateur crée l'animation comme étant une transition d'une keyframe à une autre.
Comparées à l'animation via JavaScript, les animations CSS peuvent être plus faciles à créer. Elles peuvent également donner de meilleures performances, car elles donnent plus de contrôle au navigateur pour afficher les frames au bon moment et les supprimer si nécessaire.
Cependant, le cout en performances de la modification des propriétés CSS varient d'une propriété à une autre. Animer des propriétés couteuses peut résulter en un ralentissement/blocage du navigateur (jank) tandis que le navigateur se débat pour obtenir un frame rate fluide.
La chronologie du rendu CSS
Le processus que le navigateur utilise pour mettre à jour la page lorsqu'une propriété CSS a changé peut être décrit comme une chronologie consistant des étapes suivantes :
- Recalculate Style (recalculer le style) : à chaque fois qu'une propriété CSS d'un élément change, le navigateur doit recalculer les styles calculés.
- Layout (disposition) : ensuite, le navigateur utilise les styles calculés pour trouver la position et la géométrie des éléments. Cette opération est appelée "layout" mais peut être également appelée "reflow".
- Paint (affichage) : enfin, le navigateur doit repeindre les éléments à l'écran. Une dernière étape qui n'est pas montrée dans cette séquence : la page peut être séparée en calques qui sont affichés indépendamment, puis combinés dans un processus appelé "Composition".
Cette séquence doit tenir dans une seule frame, vu que l'écran n'est pas mis à jour avant sa complétion. Il est généralement accepté que 60 frames par secondes est le frame rate auquel les animations apparaitront fluides. Un frame rate de 60 frames par secondes (fps) donne au navigateur 16.7 millisecondes pour exécuter entièrement cette séquence.
Cout des propriétés CSS
Lors de l'exécution de la chronologie du rendu CSS, certaines propriétés sont plus couteuses que d'autres :
Nom de la propriété | Cout | Exemples |
---|---|---|
Les propriétés qui impactent la forme d'un élément ou sa position déclenchent une recalculation du style, une disposition, et un repaint. | ||
Les propriétés qui n'impactent pas la forme d'un élément ou sa position, mais qui ne sont pas dans leur propre calque, ne déclenchent pas de disposition (layout) |
||
Les propriétés dans leur propre calque ne déclenchent même pas un repaint, car la mise à jour est gérée dans la composition. | transform opacity |
Le site web CSS Triggers affiche le cout pour chacune des propriétés CSS. Cela n'est valable que pour les navigateurs WebKit, mais la plupart des couts seront les mêmes dans tous les navigateurs récents.
Example : margin
contre transform
Dans cette section, la façon dont la Chronologie peut mettre en évidence la différence entre une animation utilisant margin
et une utilisant transform
serra démontrée.
L'intention de ce scénario n'est pas de convaincre que l'animation en utilisant margin
est forcement une mauvaise idée. Mais plutôt de démontrer comment les outils de développement peuvent donner une idée du travail qu'effectue le navigateur pour afficher un site web, et comment utiliser ces renseignements pour régler les problèmes de performance..
Si vous voulez expérimenter en même temps, le site de la démo est disponible ici. Il ressemble à ceci :
Le site comporte deux boutons : un pour démarrer/arrêter l'animation, et un groupe pour sélectionner le type d'animation.
Il y a quelques éléments, et ceux-ci ont les propriétés CSS linear-gradient
et box-shadow
, car elles sont relativement couteuses.
Il existe également une version vidéo de cette démo.
Animer en utilisant margin
Il faut laisser l'option "Use margin" sélectionnée, puis lancer l'animation. Il faut ensuite ouvrir l'outil Performances (maj+F5) et faire un enregistrement, seulement quelques secondes sont nécessaires.
En ouvrant l'enregistrement, ce que vous verrez dépend grandement de votre machine et de la charge du système, mais cela devrait ressembler à ceci :
Cette capture d'écran montre trois vues distinctes : une vue d'ensemble de la chronologie, le frame rate, et les détails de la frise chronologique.
Vue d'ensemble de la chronologie
Il s'agit d'une représentation compressée de la Chronologie. La prédominance du vert révèle que la page passe beaucoup de temps à peindre..
Frame rate
Cette partie montre le frame rate. Le frame rate moyen est de 46.67fps, bien en dessous de la cible de 60fps. Pire, le frame rate n'est pas du tout constant, avec un nombre conséquent de décentes dans les 20fps. Il est donc peu probable que l'animation soit fluide, surtout si une interaction utilisateur est ajoutée.
Chronologie
Le reste de l'enregistrement montre la vue de la chronologie. En faisant défiler un peu, on trouve le pattern suivant :
Cela représente la chronologie du rendu. À chaque frame de l'animation, les styles de chaque élément sont recalculés, puis composés en une seule disposition, et enfin le repaint a lieu.
Il est facile de voir que le paint prend beaucoup de performance ici. Dans la capture d'écran ci-dessus, une opération paint est mise en surbrillance. La partie sur la droite révèle que cette opération prend 13.11ms. Avec seulement 16.7ms de budget temps par frame, il n'est pas surprenant d'avoir un frame rate si bas.
Vous pouvez expérimenter avec l'exemple : essayez d'enlever la propriété box-shadow
en utilisant l'Inspecteur, et regardez comment cela affecte le temps que prend paint. Par la suite, nous verrons comment utiliser transform
au lieu de margin
élimine complètement ces paint couteux.
Animer en utilisant transform
En cliquant sélectionnant l'option "Use transform", et en effectuant un nouvel enregistrement, on obtient quelque chose ressemblant à ceci :
Vue d'ensemble de la chronologie
En comparaison avec la version utilisant margin, on remarque beaucoup moins de vert et beaucoup plus de rose, ce qui peut être soit du positionnement soit de la recalculation de style.
Frame rate
En comparaison avec la version utilisant margin, cela semble bien mieux. Le frame rate moyen est quasiment à 60fps et le frame rate est quasiment constant.
Chronologie
La frise chronologique montre la raison pour laquelle le frame rate s'est amélioré. The timeline view shows the reason for the improved frame rate. Contrairement à la version utilisant margin aucun temps n'est dépensé dans la disposition ou dans paint :
Dans ce cas-là, utiliser transform
a considérablement amélioré la performance du site, et l'outil de performance permet de voir comment et pourquoi.