Bien que cette question est un peu plus âgé, je veux répondre à ça parce que je vois souvent des scripts, où beaucoup de ces techniques sont utilisées à mauvais escient.
En général, tous votre demande d'outils (rAF
, rIC
et passive auditeurs) sont d'excellents outils et de ne pas disparaître bientôt. Mais vous devez savoir pourquoi les utiliser.
Avant de commencer: Dans le cas où vous générez de défilement synchronisé/défilement lié effets comme des effets de parallax/collant les éléments, la limitation de l'aide d' rIC
, setTimeout
n'a pas de sens parce que vous voulez réagir immédiatement.
requestAnimationFrame
rAF
vous donne le point à l'intérieur du cadre de vie, cycle de droit avant que le navigateur veut calculer le nouveau style et mise en page du document. C'est pourquoi il est parfait à utiliser pour les animations. D'abord il ne sera pas appelé plus souvent ou moins souvent que le navigateur calcule page (à droite de la fréquence). Deuxièmement, elle est appelée juste avant que le navigateur ne calculer la mise en page (bon moment). En fait, à l'aide de rAF
pour toutes les modifications de mise en page (DOM ou CSSOM changements) fait beaucoup de sens. rAF
est synchronisée avec la V-SYNC comme toute autre disposition rendu les choses liées dans le navigateur.
à l'aide de rAF
pour les gaz/anti-rebond
La valeur par défaut exemple de Paul Lewis ressemble à ceci:
var scheduledAnimationFrame;
function readAndUpdatePage(){
console.log('read and update');
scheduledAnimationFrame = false;
}
function onScroll (evt) {
// Store the scroll value for laterz.
lastScrollY = window.scrollY;
// Prevent multiple rAF callbacks.
if (scheduledAnimationFrame){
return;
}
scheduledAnimationFrame = true;
requestAnimationFrame(readAndUpdatePage);
}
window.addEventListener('scroll', onScroll);
Ce motif est très souvent utilisé, copié, bien qu'il semble à peu jusqu'pas de sens dans la pratique. (Et je me demande pourquoi aucun développeur ne voit ce problème évident.) En général, théoriquement, il fait beaucoup de sens à gaz tout au moins de la rAF
, car il n'est pas logique de demander des modifications de mise en page à partir du navigateur le plus souvent le navigateur rend la mise en page.
Cependant, l' scroll
événement est déclenché chaque fois que le navigateur rend un parchemin de changement de position. Cela signifie un scroll
événement est synchronisé avec le rendu de la page. Littéralement la même chose qu' rAF
est de vous donner. Cela signifie qu'il ne ferait aucun sens de l'accélérateur quelque chose par quelque chose, c'est déjà étranglé par exactement la même chose, par définition.
Dans la pratique, vous pouvez vérifier ce que je viens de dire par l'ajout d'un console.log
et de vérifier comment souvent ce motif "empêche plusieurs rAF rappels" (réponse n'en est aucune, sinon, ce serait un bug lié au navigateur).
// Prevent multiple rAF callbacks.
if (scheduledAnimationFrame){
console.log('prevented rAF callback');
return;
}
Comme vous le verrez, ce code n'est jamais exécutée, il est tout simplement mort de code.
Mais il y a une tendance similaire qui font sens pour une raison différente. Il ressemble à ceci:
//declare box, element, pos
function writeLayout(){
element.classList.add('is-foo');
}
window.addEventListener('scroll', ()=> {
box = element.getBoundingClientRect();
if(box.top > pos){
requestAnimationFrame(writeLayout);
}
});
Avec ce modèle, vous pouvez réduire ou même de supprimer la disposition en se débattant. L'idée est simple: à l'intérieur de votre défiler écouteur vous lire de mise en page et de décider si vous avez besoin de modifier le DOM et ensuite d'appeler la fonction qui modifie le DOM à l'aide de la rAF. Pourquoi est-ce utile? L' rAF
permet de s'assurer que vous placez votre mise en page à l'annulation (à l'ende de l'image). Cela signifie tout autre code qui est appelé à l'intérieur du même cadre de travaux sur une disposition valide et peut fonctionner avec de super rapides à disposition de méthodes de lecture.
Ce modèle est en fait si grande, que je suggère la méthode helper suivante (écrit en ES5):
/**
* @param fn {Function}
* @param [throttle] {Boolean|undefined}
* @return {Function}
*
* @example
* //generate rAFed function
* jQuery.fn.addClassRaf = bindRaf(jQuery.fn.addClass);
*
* //use rAFed function
* $('div').addClassRaf('is-stuck');
*/
function bindRaf(fn, throttle){
var isRunning, that, args;
var run = function(){
isRunning = false;
fn.apply(that, args);
};
return function(){
that = this;
args = arguments;
if(isRunning && throttle){return;}
isRunning = true;
requestAnimationFrame(run);
};
}
requestIdleCallback
Est à partir de l'API similaire à l' rAF
mais donne quelque chose de totalement différent. Il vous donne un peu de temps de repos à l'intérieur d'un cadre. (Normalement le point après que le navigateur a calculé mise en page et fait de la peinture, mais il y a encore un peu de temps jusqu'à ce que le v-sync qui se passe.) Même si la page est lag de la vue des utilisateurs, il y a peut être des images, où le navigateur est au ralenti. Bien qu' rIC
peut vous donner de max. 50ms. La plupart du temps, vous avez entre 0,5 et 10 ms pour accomplir votre tâche. Dû au fait, à quel point dans le cadre du cycle de vie rIC
rappels sont appelés, vous ne devez pas modifier le DOM (utiliser rAF
pour cette).
À la fin, il fait beaucoup de sens à gaz, scroll
écouteur pour lazyloading, infini défilement et telles que l'utilisation d' rIC
. Pour ces types d'interfaces utilisateur vous pouvez même l'accélérateur plus et ajouter un setTimeout
, en face de lui. (si vous ne 100ms attendre et puis un rIC
) (par exemple la Vie d'un anti-rebond et de gaz.)
Voici également un article sur rAF
, qui comprend deux schémas qui pourraient aider à comprendre les différents points à l'intérieur d'un "cadre" cycle de vie".
Passive écouteur d'événement
Passive des écouteurs d'événement ont été inventés pour améliorer le défilement de la performance. Les navigateurs modernes déplacé en page de défilement (rendu) dans le thread principal de la composition du fil. (voir https://hacks.mozilla.org/2016/02/smoother-scrolling-in-firefox-46-with-apz/)
Mais il y a des événements qui produisent de défilement, ce qui peut être évité par le script (ce qui arrive dans le thread principal et ne peut donc revenir à l'amélioration de la performance).
Ce qui signifie que dès que l'un de ces événements les auditeurs sont tenus, le navigateur n'a plus à attendre de ces auditeur à être exécuté avant que le navigateur peut calculer le défilement. Ces événements sont principalement touchstart
, touchmove
, touchend
, wheel
et, en théorie, à un certain degré, keypress
et keydown
. L' scroll
événement en lui-même n'est pas l'un de ces événements. L' scroll
événement n'a aucune action par défaut, qui peut être prévenue par le script.
Cela signifie que si vous n'utilisez pas l' preventDefault
votre touchstart
, touchmove
, touchend
et/ou wheel
, toujours utiliser la passivité des écouteurs d'événement et vous devriez être bien.
Dans le cas où vous utilisez preventDefault, vérifier si vous pouvez le remplacer par du CSS touch-action
de la propriété ou à la baisse, au moins, dans votre arborescence DOM (par exemple aucun cas, la délégation de ces événements). Dans le cas d' wheel
d'auditeurs, vous pourriez être en mesure de lier/délier sur mouseenter
/mouseleave
.
Dans le cas de tout autre événement: Il ne fait pas de sens pour une utilisation passive des écouteurs d'événement pour améliorer les performances. Le plus important à noter: L' scroll
événement ne peut pas être annulée et, par conséquent, il ne jamais fait sens pour l'utilisation passive des écouteurs d'événement pour scroll
.
Dans le cas d'un infini défilement vous n'avez pas besoin d' touchmove
, vous avez seulement besoin d' scroll
, de manière passive, les écouteurs d'événement ne sont pas encore applicables.
Résumé
Pour répondre à votre question
- pour lazyloading, une infinité de vue de l'utilisation d'une combinaison d'
setTimeout
+ requestIdleCallback
pour vos écouteurs d'événements et d'utiliser rAF
pour toute mise en page, écrit DOM (mutations).
- pour l'instant les effets de toujours utiliser
rAF
pour toute mise en page, écrit DOM (mutations).