Pourquoi certaines animations sont-elles lentes ?

Les navigateurs modernes peuvent animer deux propriétés CSS à faible coût: transform et opacity. Si vous animez autre chose, il est probable que vous n'atteigniez pas les 60 images par seconde (FPS). Cet article explique pourquoi.

Performances de l'animation et fréquence d'images

Il est largement admis qu'une fréquence d'images de 60 FPS est la cible lorsque vous animez un élément sur le Web. Cette fréquence d'images garantit la fluidité de vos animations. Sur le Web, un frame correspond au temps nécessaire pour effectuer tout le travail requis pour mettre à jour et repeindre l'écran. Si chaque frame ne se termine pas dans un délai de 16,7 ms (1 000 ms / 60 ≈ 16,7), les utilisateurs percevront le délai.

Le pipeline de rendu

Pour afficher un élément sur une page Web, le navigateur doit suivre les étapes séquentielles suivantes:

  1. Style: calcule les styles qui s'appliquent aux éléments.
  2. Mise en page: génère la géométrie et la position de chaque élément.
  3. Peinture: remplissez les pixels de chaque élément en calques.
  4. Composite: dessine les calques à l'écran.

Ces quatre étapes sont appelées pipeline de rendu du navigateur.

Lorsque vous animez un élément sur une page déjà chargée, ces étapes doivent être répétées. Ce processus commence à l'étape qui doit être modifiée pour permettre l'animation.

Comme indiqué précédemment, ces étapes sont séquentielles. Par exemple, si vous animez un élément qui modifie la mise en page, les étapes de peinture et de composition doivent également être exécutées à nouveau. Animer un élément qui modifie la mise en page est donc plus coûteux que d'animer un élément qui ne modifie que la composition.

Animer les propriétés de mise en page

Les modifications de mise en page impliquent de calculer la géométrie (position et taille) de tous les éléments concernés par la modification. Si vous modifiez un élément, la géométrie des autres éléments devra peut-être être recalculée. Par exemple, si vous modifiez la largeur de l'élément <html>, l'un de ses enfants peut être affecté. En raison de la façon dont les éléments débordent et s'influencent les uns les autres, les modifications plus bas dans l'arborescence peuvent parfois entraîner des calculs de mise en page jusqu'en haut.

Plus l'arborescence des éléments visibles est importante, plus le calcul de la mise en page prend du temps.

Animer les propriétés de la peinture

La peinture consiste à déterminer dans quel ordre les éléments doivent être peints à l'écran. Il s'agit souvent de l'exécution la plus longue de toutes les tâches du pipeline.

La plupart des opérations de peinture dans les navigateurs modernes sont effectuées dans des rastreurs logiciels. Selon la manière dont les éléments de votre application sont regroupés en calques, d'autres éléments en plus de celui qui a été modifié peuvent également avoir besoin d'être peints.

Animer des propriétés composites

Le compositing consiste à séparer la page en calques, à convertir les informations sur l'apparence de la page en pixels (rastreisation) et à assembler les calques pour créer une page (compositing).

C'est pourquoi la propriété opacity est incluse dans la liste des éléments peu coûteux à animer. Tant que cette propriété se trouve dans sa propre couche, les modifications apportées peuvent être gérées par le GPU lors de l'étape de composition. Les navigateurs Chromium et WebKit créent une nouvelle couche pour tout élément ayant une transition ou une animation CSS sur opacity.

Qu'est-ce qu'un calque ?

En plaçant les éléments qui seront animés ou mis en transition sur une nouvelle couche, le navigateur n'a besoin de repeindre que ces éléments et non tout le reste. Vous connaissez peut-être le concept de calque de Photoshop, qui contient un ensemble d'éléments pouvant être déplacés ensemble. Les calques de rendu du navigateur sont semblables à cette idée.

Bien que le navigateur prenne de bonnes décisions sur les éléments à placer sur une nouvelle couche, s'il en manque un, il existe des moyens de forcer la création de la couche. Pour en savoir plus, consultez Créer des animations hautes performances. Cependant, la création de nouvelles couches doit être effectuée avec précaution, car chaque couche utilise la mémoire. Sur les appareils dont la mémoire est limitée, la création de nouvelles couches peut entraîner un problème de performances plus important que celui que vous essayez de résoudre. De plus, les textures de chaque calque doivent être importées dans le GPU. Par conséquent, vous risquez de rencontrer des contraintes de bande passante entre le CPU et le GPU.

Performances du CSS par rapport à JavaScript

Vous vous demandez peut-être s'il est préférable, du point de vue des performances, d'utiliser du code CSS ou JavaScript pour les animations.

Les animations basées sur CSS et les animations Web (dans les navigateurs compatibles avec l'API) sont généralement gérées sur un thread appelé thread du moteur de rendu. Il s'agit d'un comportement différent de celui du thread principal du navigateur, où le style, la mise en page, la peinture et JavaScript sont exécutés. Cela signifie que si le navigateur exécute des tâches coûteuses sur le thread principal, ces animations peuvent continuer sans être interrompues.

Comme expliqué dans cet article, d'autres modifications des transformations et de l'opacité peuvent, dans de nombreux cas, également être gérées par le thread du moteur de rendu.

Si une animation déclenche la peinture, la mise en page ou les deux, le thread principal doit effectuer des tâches. C'est le cas pour les animations CSS et JavaScript. La surcharge de la mise en page ou de la peinture va probablement éclipser toute tâche associée à l'exécution CSS ou JavaScript, rendant la question inutile.