Debounce vs throttle en JavaScript, en visualisation | We.Inc
Déplacez votre pointeur sur la zone et observez les événements bruts, les appels avec debounce et les appels avec throttle sur une même frise. Fonctions debounce et throttle à copier, avec des hooks React.
Le debounce attend que les appels cessent pendant un délai donné, puis s'exécute une fois, ce qui convient aux champs de recherche et à l'enregistrement automatique. Le throttle s'exécute au plus une fois par intervalle tant que les appels continuent, ce qui convient au défilement, au redimensionnement et au suivi du pointeur. Les deux prennent une fonction et un délai en millisecondes, et renvoient une fonction enveloppée que vous appelez à la place.
Lequel utiliser
Situation
À utiliser
Pourquoi
Recherche pendant la saisie
Debounce, environ 300 ms
Une seule requête quand la personne marque une pause
Enregistrement automatique d'un formulaire
Debounce, environ 1000 ms
Enregistrer une fois la saisie terminée
Position de défilement ou barre de progression
Throttle, environ 100 ms
Mises à jour régulières pendant le défilement
Calculs de mise en page au redimensionnement de la fenêtre
Throttle ou debounce
Throttle pour un retour en direct, debounce pour la taille finale
Éviter les doubles clics d'envoi
Debounce sur le front montant (leading)
Le premier clic compte, les répétitions sont ignorées
On confond souvent les deux termes, car tous deux réduisent la fréquence d'exécution d'une fonction. La zone ci-dessous montre la différence sur une frise commune : chaque événement brut sous forme de trait fin, chaque appel avec debounce et chaque appel avec throttle sous forme de point. Changez le délai et le motif change avec lui.
Déplacez votre pointeur ou votre doigt sur la zone, ou maintenez une touche enfoncée quand elle a le focus.
Les événements bruts remplissent la piste du haut. La piste du milieu montre les appels avec debounce, celle du bas les appels avec throttle.
Faites glisser le curseur de délai et recommencez pour voir comment l'écart modifie les deux motifs.
Copiez ci-dessous les fonctions simples ou les hooks React pour votre propre code.
Créez la fonction avec debounce une seule fois. En créer une nouvelle à chaque rendu React réinitialise son minuteur, et elle ne se déclenche jamais.
Annulez les appels en attente quand un composant est démonté, sinon un appel tardif risque de mettre à jour quelque chose qui n'existe plus.
Pour les animations liées au défilement, requestAnimationFrame fait souvent mieux qu'un intervalle de throttle fixe.
Appliquez le debounce à la partie coûteuse, comme la requête réseau, pas à l'état du champ lui-même, sinon la saisie paraît lente.
Questions fréquentes
Quelle est la différence entre debounce et throttle ?
Le debounce relance son minuteur à chaque appel et ne s'exécute qu'une fois les appels interrompus. Le throttle ignore les appels dans la fenêtre en cours mais s'exécute de nouveau dès que la fenêtre est passée : il se déclenche donc régulièrement pendant une longue rafale.
Que sont les fronts leading et trailing ?
Le front leading est le premier appel d'une rafale ; le front trailing est le moment où se termine l'intervalle de la rafale. Un debounce trailing s'exécute après la pause, un debounce leading s'exécute immédiatement puis ignore les appels jusqu'à la pause. Les throttles peuvent se déclencher sur l'un des fronts ou sur les deux.
Ai-je besoin de lodash pour le debounce ?
Non. Les fonctions de cette page tiennent en quelques lignes chacune. Une version issue d'une bibliothèque ajoute des options comme maxWait, cancel et flush, pratiques mais faciles à ajouter vous-même si vous n'en avez besoin que d'une.
Quelle durée de délai choisir ?
Il n'existe pas de chiffre unique. Commencez autour de 300 millisecondes pour la saisie et 100 pour le défilement ou le pointeur, puis ajustez au ressenti. Plus court paraît plus réactif mais économise moins de travail.
Comment fonctionne le debounce
Chaque appel annule le minuteur en attente et en démarre un nouveau. La fonction d'origine ne s'exécute que lorsque le minuteur tient jusqu'au bout du délai, avec les arguments du dernier appel.
Le debounce est donc idéal pour saisir une intention : chaque frappe ne vous intéresse pas, seulement le mot que la personne a fini de taper. Le prix à payer est la latence, puisque rien ne se passe avant la pause.
Comment fonctionne le throttle
Un throttle mémorise le moment de sa dernière exécution. Un appel dans l'intervalle est abandonné ou, dans la version trailing, conservé pour s'exécuter à la fin de l'intervalle. Les appels hors de l'intervalle s'exécutent immédiatement.
Utilisez-le quand l'utilisateur doit voir un retour continu, comme un en-tête fixe qui réagit au défilement, mais qu'une exécution à chaque événement serait du gaspillage.
Versions en JavaScript pur
debounce(fn, wait)
Front trailing. cancel() abandonne tout appel en attente.
throttle(fn, wait)
S'exécute sur le front leading, puis une fois encore à la fin de la fenêtre si des appels sont arrivés entre-temps : la dernière valeur n'est donc jamais perdue.
Hooks React
useDebouncedCallback
Garde un seul minuteur pendant toute la vie du composant, appelle toujours le callback le plus récent et efface le minuteur au démontage.
useThrottledValue
Renvoie une copie d'une valeur qui change vite, mise à jour au plus une fois par intervalle.
Événements bruts
Debounce ({n} ms)
Throttle ({n} ms)
Visualiseur
Passez sur la zone. Les traits fins sont les événements bruts ; les points sont les appels réellement exécutés après debounce ou throttle.
Délai : {n} ms
Zone d'événements : déplacez le pointeur ici ou maintenez une touche
Passez ici (ou donnez le focus et maintenez une touche)
La frise montre les six dernières secondes ; les chiffres comptent les appels dans cette fenêtre.