Best of web 2016 : web animation performance

Avec la multiplication des application en ligne (one page applications), il est possible de proposer une expérience utilisateur enrichie avec des interfaces animées.

Comment faire des animations fluides ? Comment analyser les performances ? Comment optimiser les performances ? Voici quelques conseils inspirés par la présentation de Freddy Harris lors du best of web 2016.
teamBOW
Aujourd’hui le web veut concurrencer les applications. Pour ce faire nous développons des one page applications. La difficulté est d’optimiser ces interfaces animées pour rendre l’expérience utilisateur la meilleure possible.
Comment faire des animations fluides ? Comment analyser les performances ?

render-engine
schema du rendu d’une page web

Le layout

Le navigateur calcule le layout et determine la position et la taille des “box” en fonction de l’interaction qu’elles ont entre elles (parents et frères.)
Les principales propriétés css utilisées pour la mise en page (display) sont :

  • Block Layout
  • Inline Layout
  • Table Layout
  • Positioned Layout
  • Flexible Box Layout
  • Grid Layout

Le paint

Apres avoir calculé les positions, le navigateur applique les styles visuels.
Les principales propriétés css utilisées pour le paint sont :

  • background
  • color
  • box-shadow
  • border-color

Le composite

L’ensemble des éléments bitmap (images, videos, canvas) sont envoyés au GPU (processeur graphique).
Le GPU applique les opérations sur les textures comme les transformations ou la transparence. Certain éléments et opérations comme les transformation 3D, la vidéo et canvas, l’animation css, la transparence, les filtres css, …  entraînent la création de layers qui seront applatis par le GPU pour obtenir le rendu de la page.
Pour optimiser le composite les développeurs utilisent parfois un hack css translateZ(0). Ce hack est fortement déconseillé et il est recommandé d’utiliser la propriété css will-change. Cette propriété indique au navigateur quel élément va changer et quelles propriétés vont changer.

Les  animations CSS

Optimiser les animations permet d’atteindre une animation fluide à 60 fps soit environ 16.6ms entre chaque image.
[youtube https://www.youtube.com/watch?v=pfiHFqnPLZ4&w=560&h=315] Prenons un exemple simple d’animation d’un carré.

<div id="container">
 <div id="test"></div>
</div>

Une premire methode consiste a animer les marges

#test {
   width: 160px;
   height:160px;
   margin: 15px;
   transition: margin 1s;
}
#test.change {
   margin-top:100px;
   margin-left:100px;
}

Pour réaliser cette animation nous obtenons sur desktop:

  • 16.74ms entre chaque images
  • 59 FPS
  • 3.23 ms de traitement processeur

et sur mobile :

  • 31.29ms entre chaque images
  • 31 FPS
  • 28.90 ms de traitement processeur

Une seconde méthode consiste a animer le carré lui même.

#test{
 width: 160px;
 height:160px;
 margin: 15px;
 transition: transform 1s;
}
#test.change{
 transform: translate(100px, 100px);
}

Nous obtenons sur desktop :

  • 16.74ms entre chaque images
  • 59 FPS
  • 3.23 ms de traitement processeur

et sur mobile :

  • 50.66ms entre chaque images
  • 19 FPS
  • 29.84 ms de traitement processeur

Enfin une troisième méthode consiste a animer le carré en y ajoutant la propriété will-change

#test{
 width: 160px;
 height:160px;
 margin: 15px;
 transition: transform 1s;
 will-change: transform;
}
#test.change{
 transform: translate(100px, 100px);
}

Nous obtenons :

  • 16.58ms entre chaque images
  • 60 FPS
  • 0 ms de traitement processeur

La propriété will-change indique au navigateur les propriétés qui vont changer. Le navigateur peut ainsi l’anticiper et prévoir les ressources necessaires pour l’optimiser.

Les animations javascript

Les animations web peuvent également être conçues en javascript. Plusieurs méthodes sont possibles pour optimiser ces animations.

requestAnimationFrame

Lors d’une animation nous devons utiliser un timer pour effectuer les transformations toutes les n ms. requestAnimationFrame permet d’optimiser les animations en les regroupant dans une même frame.
Elle est appelée avant le rendu de l’animation.

function draw() {
 requestAnimationFrame(draw);
 // le code de votrte animation
}
requestAnimationFrame(draw);

L’animation est optimisée car elle est parfaitement synchronisée. Par conséquent elle demandera moins de ressource au processeur graphique.
Le debouncing permet de regrouper plusieurs appels en un seul. Cette fonction est utile pour les animations de type scroll, mouse et touch event car les évènements sont appelés très fréquemment et le gestionnaire d’évènement n’est pas fait pour en supporter autant.

Web animation API

Cette technique javascript native permet de créer des animations plus complexes, de les contrôler et séquencer de facon aussi efficace que les animation CSS.

element.animate([
   {transform: 'translate(200px, -100%)'},
   {transform: 'translate(200px, ' + window.innerHeight + 'px)'}
 ], {
   duration: 1500,
   iterations: 10,
   delay: 300
 });

Ce type d’animation ne nécessite pas de chargement de scripts externes ce qui optimise l’animation.
Cet article et inspiré par la présentation de Freddy Harris lors du best of web 2016.
harry
Antoine Duplouy, UX-Scientist @UXRepublic