Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Les Performance de rendu sur mobile

1,829 views

Published on

Comment avoir un rendu performant même sur mobile ? Comment animer convenablement ses interfaces Web ? Quelques pistes et retours d'expérience.
Présenté en 2015 pour le JS Open days 1

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Les Performance de rendu sur mobile

  1. 1. Les performances de rendu Jean-Pierre Vincent Architecte itinérant Consultant et Formateur Perfs ou JS @theystolemynick
  2. 2. POURQUOI FAIRE ?
  3. 3. Pour faire plaisir à l’utilisateur (et ton CA) Temps de réponse : • < 150 ms : instantané – Le but de toute interface touch • 150 ms — 1 s : c’est la machine qui bosse – L’utilisateur stresse • > 10s : bye bye Animations : • 60 Fps : fluide et naturel • < 30 Fps : bye bye
  4. 4. Pour faire plaisir à Dieu
  5. 5. Pour faire des interfaces très réactive
  6. 6. Pour des interactions plus riches
  7. 7. Avoir 60 Fps ou pas
  8. 8. Comment fluidifier ? $(‘.el1’).animate( { left: ‘-=600’ }, { duration: 350, easing: ‘bounce’ } ); $(‘.el2’).animate …
  9. 9. Les ordres de grandeur 60 Hz = 16 ms pour : • JS – Récupérer la position de l’élément – Calcul de la nouvelle position – Appliquer la nouvelle position • Navigateur – Calculs de Layout – Paint des zones modifées – Pousser vers la carte graphique
  10. 10. Les manipulations DOM en JS • el.offsetLeft …, el.clientLeft…, el. getBoundingClientRect()… • el.scrollTo(), el.scrollTop, w.innerHeight • el.getComputedStyle() • evt.layerX, evt.offsetX • SVG.getCharNumAtPosition(), SVG.getNumberOfChars() jQuery.animate() utilise tout cela !
  11. 11. Animation prédictible ? JS quasi inutile • On trash jQuery.animate • Pré-calcul des styles • JS se limite à ajouter / supprimer des classes El1.addClass(‘disappear-to-left’) El2.addClass(‘appear-from-right’)
  12. 12. Animation prédictible : transition CSS .elements { transition-property : left; transition-timing-function: cubic- bezier(0,0,0.25,1); transition-duration : 350 ms; left: 600px; } .appear-from-right { left: 0; } .disappear-to-left { left: -600px; }
  13. 13. Transitions CSS • JS : – Récupérer la position de l’élément – Calcul de la nouvelle position – Appliquer la nouvelle position • Navigateur – Calculs de Layout – Paint des zones modifées – Pousser vers la carte graphique
  14. 14. Les propriétés qui coûtent cher Elles déclenchent Layout + Paint + Composite • top, left, width, height, float • font-*, border-*, padding-*, margin-* • display, visibility csstriggers.com
  15. 15. Les propriétés qui vont bien .move-left{ transform: translateX(-600px); } .enlarge-your p { transform : scale(1.3, 0) ; } • IE 8 : ms-filters, IE9 : prefix ms- • IE10, chrome, Fx, OS mobile : standard
  16. 16. CSS transform / opacity • JS : – Récupérer la position de l’élément – Calcul de la nouvelle position – Appliquer la nouvelle position • Navigateur – Calculs de Layout – Paint des zones modifées – Pousser vers la carte graphique
  17. 17. Bonus : forcer le GPU (parfois) .move-left { transform:translate3d(-600px, 0, 0); } .enlarge-your p { transform:scale3d(1.3, 0, 0); }
  18. 18. Transition + translation + GPU = <3 .elements { transition-property : transform; transition-timing-function: cubic- bezier(0,0,0.25,1); transition-duration : 350 ms; left: 600px; } .appear-from-right { transform: translate3d(-600px, 0px, 0px); } .disappear-to-left { transform: translate3d(-1200px, 0px, 0px); }
  19. 19. Transition + translation + GPU = <3 • JS : – Récupérer la position de l’élément – Calcul de la nouvelle position – Appliquer la nouvelle position • Navigateur – Calculs de Layout – Paint des zones modifées – Pousser vers la carte graphique
  20. 20. 60 FPS FTW
  21. 21. LES ANIMATIONS IMPRÉVISIBLES
  22. 22. Et pour les animations imprévisibles ? • Parallax • Drag • Jeux vidéos • …
  23. 23. Reprenons • JS : – Récupérer la position de l’élément – Calcul de la nouvelle position – Appliquer la nouvelle position • Navigateur – Calculs de Layout <= optimisé en CSS – Paint des zones modifées <= optimisé en CSS – Pousser vers la carte graphique
  24. 24. Récupérer la position : mise en cache • Plutôt que $(el).on(‘touchmove’, function move() { // get + set du DOM en boucle : BOOM this.style.width = (this.offsetWidth + X); } • Préférer var width = el.offsetWidth; $(el).on(‘touchmove’, function move() { // un set, et même plusieurs d’affilé : SMOOTH this.style.width = ( width += Y ); }
  25. 25. Reprenons • JS : – Récupérer la position de l’élément – Calcul de la nouvelle position – Appliquer la nouvelle position • Navigateur – Calculs de Layout – Paint des zones modifées – Pousser vers la carte graphique
  26. 26. Quand mettre à jour le DOM ? // JAMAIS setInterval( move, 16 ); // MIEUX, mais agressif et imprécis (function boucle() { setTimeout( boucle, 16); move(); }()); // AU TOP (function boucle() { requestAnimationFrame( boucle); move(); }());
  27. 27. Alléger var height = el.offsetHeight, Y = 0; $(el).on(‘touchmove’, function calculateDelta() { … // Calcul séparé de Y (delta du doigt) }); requestAnimationFrame( function move() { … // check de la nécessité puis Raf(move) this.style.height = (height += Y); });
  28. 28. Reprenons • JS : – Récupérer la position de l’élément – Calcul de la nouvelle position <= dissocié – Appliquer la nouvelle position <= optimisé • Navigateur – Calculs de Layout – Paint des zones modifées – Pousser vers la carte graphique
  29. 29. Calculs lourds ? var IA = new Worker(‘game-ia.js’); var positions; IA.addEventListener(‘moves’,function(e){ positions = e.data; }); (function boucle() { requestAnimationFrame( boucle ); moveUnits( positions ); })();
  30. 30. Calculs lourds ? La technique ancestrale du setTimeout( fn, 0); Universel, increvable, lisible avec le bon snippet
  31. 31. Reprenons • JS : – Récupérer la position de l’élément – Calcul de la nouvelle position <= dissocié et optimisé – Appliquer la nouvelle position <= optimisé • Navigateur – Calculs de Layout – Paint des zones modifées – Pousser vers la carte graphique
  32. 32. DOM : la taille compte (et la manière dont on s’en sert) DOM Monster yellowlab.tools
  33. 33. Touche pas (trop) à mon DOM • Peu de requête DOM – Mise en cache des résultats en dehors des boucles • Appliquer en batchs – $el.addClass(‘error’) plutôt que $el.css – .innerHTML marche encore ! – Pas d’alternance get / set
  34. 34. Apprends à faire tes sélecteurs • Natif quand tu peux : $(document.getElementById(‘id’)) VS $(‘#id’) document.querySelector(‘.item’) VS $(‘.item’).first() • Limiter l’étendue de la recherche $container.find(‘.item’) $container.find(‘ > li.item’) • Déléguer $container.on( ‘click’, ‘li’, function(){} )
  35. 35. MAÎTRISER SES OUTILS Assez de règles
  36. 36. Profilers — Android & Desktop
  37. 37. Profilers — Firefox & Firefox OS
  38. 38. Profilers — Windows
  39. 39. Profilers natifs — iOS & desktop
  40. 40. Les autres • Opera : dragonfly • IE8 : profiling JS À l’instinct™ : • iOS < 7 • Navigateur Android • …
  41. 41. Librairies d’animation CSS 3 • Librairies CSS: – animate.css, – Effekt.css • Librairies JS : – D3.js, – GSAP, – TweenJS, – jQuery 4
  42. 42. Conclusion • JS seul est performant, merci de demander • Watch your DOM ! • Use the CSS 3 / HTML5 force Luke Je testerais, tu testeras, nous testerons …
  43. 43. MERCI Jean-Pierre Vincent @theystolemynick Un audit ou une petite formation Perfs ? jp@braincracking.fr

×