web-dev-qa-db-fra.com

Comparaison des performances Javascript OnScroll

Mise à jour : question similaire avec une très bonne réponse qui montre comment utiliser requestAnimationFrame avec défilement d'une manière utile: événements de défilement: requestAnimationFrame VS requestIdleCallback Écouteurs d'événements passifs VS


Disons donc que je veux ajouter une action coûteuse sur mon site déclenchée par le défilement. Par exemple, j'utilise des effets de parallaxe dans mon jsfiddle.

Maintenant, je continue à lire qu'il ne doit pas être lié directement à l'événement, parfois suivi d'extraits qui sont censés être meilleurs. Quelques exemples:

  1. Attacher des gestionnaires JavaScript aux événements de défilement = MAUVAIS!
  2. Comment développer un événement onScroll haute performance?
  3. Comment faire des effets de défilement plus rapides?
  4. écouteur d'événement onscroll 60FPS

Ce qu'ils disent, c'est que ce n'est pas le cas:

  // Bad guy 1
  $(window).scroll( function() {
    animate(ex1);
  });

ou ca

  // Bad guy 2
  window.addEventListener('scroll', onScroll, false);
  function onScroll() {
    animate(ex2);
  }

Mais utilisez des délais d'expiration, des intervalles, requestAnimationFrame et ainsi de suite, par exemple:

  // Good guy
  $(window).scroll( function() {
   scrolling1 = true;
  });

  setInterval( function() {
    if (scrolling1) {
      scrolling1 = false;
      animate(ex3);
    }
  }, 50 );

Je suis donc allé ajouter les options que j'ai trouvées dans les liens ci-dessus à un jsfiddle qui essaie de les comparer en ajoutant un compteur à chaque approche, comme ceci:

  // Test
  $(window).scroll( function() {
    counter = counter + 1;
    // output result of counter
    animate(ex1);
  });

Mieux vaut vérifier l'intégralité de jsfiddle ou l'utiliser pour les anciens navigateurs: Scrolltest (le même, mais pas sur jsfiddle)

Résultat : Tout ce qui fonctionne bien est à peu près le même nombre de calculs. Si je peux vivre avec des effets saccadés, je peux peut-être sécuriser certaines ressources. Et contre tout ce que je lis, cela me semble logique!

Première question: Suis-je en train de manquer quelque chose ou est-ce un test valide? S'il n'est pas valide, comment pourrais-je tester correctement? Modifier: Pour clarifier, je veux tester si l'une des méthodes ci-dessus permet d'économiser les performances.

Deuxième question: Si elle est valable, pourquoi tout le monde est-il nerveux à propos d'onscroll? Si les animations fluides nécessitent 5000 calculs sur le site complet, il n'y a aucun moyen de le changer de toute façon?

(Eh bien, parfois j'utilise des vérifications pour déterminer si un objet est dans la fenêtre ou non, mais honnêtement, je ne sais même pas si ces vérifications ne sont pas aussi chères que le code empêché lui-même, surtout si elles impliquent cinq variables différentes telles que offset, windowHeight, scrolltTop, getBoundingClientRect et externeHeight ...)

13
user127091

Donc, @SirPeople a déjà répondu correctement à votre première question, c'est en effet un bon test pour voir à quelle fréquence la fonction d'animation est appelée, mais c'est un mauvais test pour comparer les performances des différents extraits.

Il s'agit d'un enregistrement de performance de l'excécution:

performance test

La fonction animate n'est pas chère du tout. J'ai pris un enregistrement de performance (photo suivante), qui montre qu'il faut entre 0,64 ms et 1,29 ms dans la seule itération que j'ai regardée (points 1-5). Et une fois la fonction terminée, la repeinture ne prend aucun temps (point 6), ce qui pourrait être dû au fait que la page n'a presque pas de contenu. Lorsque nous jetons un coup d'œil à l'heure, nous pouvons voir que les cinq fonctions d'animation et le repeint se produisent en moins de 10 ms, ce qui, dans des circonstances normales, signifie que nous pouvons obtenir une animation fluide à 60 images par seconde (point 7).

De plus, si nous voulons comparer les écouteurs d'événements onscroll, nous devons tester chacun d'eux et comparer les résultats. Si l'un des auditeurs bloquait vraiment, cela aurait une influence sur toute la page et sans débogage des performances, vous ne sauriez pas lequel.

J'ai fait deux jsfiddles window.scroll et RAF . Et, à ma grande surprise, il ne semble pas y avoir de différence.

Pourquoi les gens sont-ils préoccupés par cela?

Comme vous pouvez le voir dans les jsfiddles liés ci-dessus, si les gestionnaires d'événements deviennent trop volumineux, la page entière va être en retard.

Et maintenant?

Je ne suis pas moi-même un gourou de la performance, mais:

5
Sandro

Je ne suis pas totalement sûr d'avoir bien compris vos questions et toutes vos déclarations mais je vais essayer de vous répondre:

  • Suis-je en train de manquer quelque chose ou est-ce un test valide? Si elle n'est pas valide, comment pourrais-je tester correctement?

C'est un test valide si vous mesurez le nombre de fois qu'une fonction a été appelée, cela dépendra bien sûr du navigateur, SO, si le GPU est amélioré et d'autres paramètres de référence qui ont déjà été commentés dans votre question.

Si nous considérons que la mesure est correcte, alors on peut dire qu'en utilisant des délais d'attente ou requestAnimationFramework pourrait gagner du temps parce que nous suivons fondamentalement les principes de anti-rebond ou limitation . Fondamentalement, nous ne voulons pas demander ou appeler une fonction plus de fois que nécessaire. Dans le cas du temporisateur, nous mettrons en file d'attente moins d'appels de fonctions et dans le cas de requestAnimationFrame car il mettra les appels en file d'attente avant de repeindre et les exécutera séquentiellement. Dans les délais d'attente, il peut arriver que les calculs se chevauchent s'ils sont très lourds.

J'ai trouvé une meilleure réponse dans pourquoi utiliser requestAnimationFrame expliquant les principaux problèmes avec les animations dans le navigateur comme Shear, scintillement ou saut de trame. Il comprend également une bonne démo.

Je pense que votre méthode de test est correcte, vous devez également l'interpréter correctement, peut-être que les appels sont proches du même numéro en raison de votre matériel et de votre moteur, mais comme dit, le rebounce et la limitation sont une amélioration des performances.

Ici aussi, un autre article soutenant de ne pas attacher les gestionnaires au défilement de la fenêtre de Twitter . (Avertissement: cet article date de 2011 et les navigateurs traitent les optimisations de défilement de différentes manières).

  • pourquoi tout le monde est nerveux à propos d'onscroll? Si les animations fluides nécessitent 5000 calculs sur le site complet, il n'y a aucun moyen de le changer de toute façon?

Je ne pense pas qu'il y ait de la nervosité dans la performance, mais l'expérience utilisateur sera pire pour les problèmes d'animation mentionnés ci-dessus que votre surappel de défilement peut provoquer, ou même s'il y a une désynchronisation avec votre minuterie, vous pourriez toujours obtenir la même chose '' problèmes de performances. Les gens recommandent simplement d'enregistrer les appels pour les faire défiler, car: la permanence visuelle humaine ne nécessite pas une fréquence d'images très élevée et il est donc inutile d'essayer de montrer des images plus souvent. Pour les calculs plus complexes ou les animations lourdes, les navigateurs travaillent déjà sur des optimisations, comme vous l'avez vérifié, certains les navigateurs avaient optimisé ces choses par rapport aux il y a 2, 3 ou 6 ans, les articles que vous exposez ont été écrits.

7
SirPeople