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.
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 ?
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.
Antoine Duplouy, UX-Scientist @UXRepublic