Maison interface Web js tutoriel Anti-rebond et limitation

Anti-rebond et limitation

Aug 09, 2024 pm 08:32 PM

Debouncing and Throttling

Une autre parmi les questions d'entretien front-end les plus populaires. Il teste les connaissances des personnes interrogées sur JS, Performance et FE System Design.

Il s'agit de la question n°2 de la série de questions d'entrevue frontale. Si vous souhaitez améliorer votre préparation ou rester à jour en général, pensez à vous inscrire sur FrontendCamp.


L'anti-rebond et la limitation fonctionnent sur le même principe - des trucs de retard - mais ont toujours une approche et des cas d'utilisation très différents.

Les deux concepts sont utiles pour développer une application performante. Presque tous les sites Web que vous visitez quotidiennement utilisent l'anti-rebond et la limitation d'une manière ou d'une autre.

Anti-rebond

Un cas d'utilisation bien connu de l'anti-rebond est la saisie anticipée (ou la saisie semi-automatique).

Imaginez que vous créez une fonction de recherche pour un site Web de commerce électronique proposant des milliers de produits. Lorsqu'un utilisateur tente de rechercher quelque chose, votre application effectue un appel API pour récupérer tous les produits correspondant à la chaîne de requête de l'utilisateur.

const handleKeyDown = async (e) => {
 const { value } = e.target;
 const result = await search(value);
 // set the result to a state and then render on UI
}

<Input onKeyDown={handleKeyDown} />

Cette approche semble correcte mais elle présente quelques problèmes :

  1. Vous effectuez un appel API à chaque événement d'appui sur une touche. Si un utilisateur tape 15 caractères, cela représente 15 appels API pour un seul utilisateur. Cela n’évoluerait jamais.
  2. Lorsque le résultat de ces 15 appels API arrive, vous n'avez besoin que du dernier. Le résultat des 14 appels précédents sera ignoré. Cela consomme beaucoup de bande passante de l'utilisateur et les utilisateurs sur un réseau lent connaîtront un retard important.
  3. Sur l'interface utilisateur, ces 15 appels d'API déclencheront un nouveau rendu. Cela rendra le composant lent.

La solution à ces problèmes est le rebond.

L'idée de base est d'attendre que l'utilisateur arrête de taper. Nous retarderons l'appel API.

const debounce = (fn, delay) => {
 let timerId;
 return function(...args) {
  const context = this;

  if (timerId) {
    clearTimeout(timerId);
  };
  timerId = setTimeout(() => fn.call(context, ...args), delay);
 }
}

const handleKeyDown = async (e) => {
 const { value } = e.target;
 const result = await search(value);
 // set the result to a state and then render on UI
}

<Input onKeyDown={debounce(handleKeyDown, 500)} />

Nous avons étendu notre code existant pour utiliser l'anti-rebond.

La fonction anti-rebond est une fonction utilitaire générique qui prend deux arguments :

  1. fn : L'appel de fonction qui est censé être retardé.
  2. delay : Le délai en millisecondes.

À l'intérieur de la fonction, nous utilisons setTimeout pour retarder l'appel réel de la fonction (fn). Si le fn est rappelé avant la fin du temps imparti, le minuteur se réinitialise.

Avec notre implémentation mise à jour, même si l'utilisateur tape 15 caractères, nous n'effectuerions qu'un seul appel API (en supposant que chaque pression sur une touche prend moins de 500 millisecondes). Cela résout tous les problèmes que nous avons rencontrés lorsque nous avons commencé à créer cette fonctionnalité.

Dans une base de code de production, vous n'aurez pas à coder votre propre fonction utilitaire anti-rebond. Il y a de fortes chances que votre entreprise utilise déjà une bibliothèque d'utilitaires JS comme lodash qui dispose de ces méthodes.

Étranglement

Eh bien, l'anti-rebond est excellent pour les performances, mais il existe certains scénarios dans lesquels nous ne voulons pas attendre x secondes avant d'être avertis d'un changement.

Imaginez que vous construisez un espace de travail collaboratif comme Google Docs ou Figma. L'une des fonctionnalités clés est qu'un utilisateur doit être informé des modifications apportées par mes autres utilisateurs en temps réel.

Jusqu'à présent, nous ne connaissons que deux approches :

  1. L'approche Noob : chaque fois qu'un utilisateur déplace le pointeur de sa souris ou tape quelque chose, effectuez un appel API. Vous savez déjà à quel point cela peut devenir grave.
  2. L'approche Debouncing : elle résout le problème des performances, mais d'un point de vue UX, c'est terrible. Votre collègue peut écrire un paragraphe de 300 mots et vous ne serez averti qu'une seule fois à la fin. Est-ce toujours considéré comme du temps réel ?

C'est là qu'intervient le Throttling. C'est juste au milieu des deux approches mentionnées ci-dessus. L'idée de base est la suivante : notifier à intervalles périodiques - pas à la fin ni à chaque pression sur une touche, mais périodiquement.

const throttle = (fn, time) => {
 let lastCalledAt = 0;

 return function(...args) {
  const context = this;
  const now = Date.now();
  const remainingTime = time - (now - lastCalledAt);

  if (remainingTime <= 0) {
   fn.call(context, ...args);
   lastCalledAt = now;
  }
 }
}

const handleKeyDown = async (e) => {
 const { value } = e.target;
 // save it DB and also notify other peers
 await save(value);
}

<Editor onKeyDown={throttle(handleKeyDown, 1000)} />

Nous avons modifié notre code existant pour utiliser la fonction d'accélérateur. Il faut deux arguments :

  1. fn : la fonction réelle d'accélérateur.
  2. time : L'intervalle après lequel la fonction est autorisée à s'exécuter.

La mise en œuvre est simple. Nous stockons l'heure à laquelle la fonction a été appelée pour la dernière fois dans lastCalledAt. La prochaine fois, lorsqu'un appel de fonction est effectué, nous vérifions si le temps s'est écoulé et ensuite seulement nous exécutons fn.

Nous y sommes presque, mais cette implémentation présente un bug. Que se passe-t-il si le dernier appel de fonction avec certaines données est effectué dans l'intervalle de temps et qu'aucun appel n'est effectué après cela. Avec notre implémentation actuelle, nous perdrons certaines données.

Pour résoudre ce problème, nous stockerons les arguments dans une autre variable et lancerons un délai d'attente qui sera appelé plus tard si aucun événement n'est reçu.

const throttle = (fn, time) => {
 let lastCalledAt = 0;
 let lastArgs = null;
 let timeoutId = null;

 return function(...args) {
  const context = this;
  const now = Date.now();
  const remainingTime = time - (now - lastCalledAt);

  if (remainingTime <= 0) {
   // call immediately
   fn.call(context, ...args);
   lastCalledAt = now;
   if (timeoutId) {
     clearTimeout(timeoutId);
     timeoutId = null;
   }
  } else {
    // call later if no event is received
    lastArgs = args;
    if (!timeoutId) {
      timeoutId = setTimeout(() => {
        fn.call(context, ...lastArgs);
        lastCalledAt = Date.now();
        lastArgs = null;
        timeoutId = null;
      }, remainingTime);
    }
  }
 }
}

Cette implémentation mise à jour garantit que nous ne manquerons aucune donnée.

Lodash fournit également une fonction utilitaire d'accélérateur.


Résumé

  1. L'anti-rebond et la limitation sont des techniques d'optimisation des performances.
  2. Ces deux fonctionnent sur un principe similaire : retarder les choses.
  3. Debounce attend t après la réception du dernier événement tandis que Throttling exécute périodiquement le fn dans t temps.
  4. L'anti-rebond est utilisé dans les fonctionnalités de recherche et la limitation est utilisée dans les applications en temps réel (sans s'y limiter).

Ressources

FrontendCamp
lodash

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Stock Market GPT

Stock Market GPT

Recherche d'investissement basée sur l'IA pour des décisions plus intelligentes

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Vercel Spa Routing et chargement des ressources: résoudre les problèmes d'accès aux URL profonds Vercel Spa Routing et chargement des ressources: résoudre les problèmes d'accès aux URL profonds Aug 13, 2025 am 10:18 AM

Cet article vise à résoudre le problème du rafraîchissement de l'URL profond ou de l'accès direct, provoquant une défaillance de chargement des ressources de la page lors du déploiement d'applications (spas) de page unique sur Vercel. Le noyau est de comprendre la différence entre le mécanisme de réécriture de routage de Vercel et les chemins relatifs d'analyse du navigateur. En configurant Vercel.json pour rediriger tous les chemins vers index.html et corriger la méthode de référence des ressources statiques dans HTML, modifiez le chemin relatif en chemin absolu, en vous assurant que l'application peut charger correctement toutes les ressources sous n'importe quelle URL.

Guide de déploiement de l'application unique de page (SPA): résolution de problèmes de chargement d'URL profonds Guide de déploiement de l'application unique de page (SPA): résolution de problèmes de chargement d'URL profonds Aug 13, 2025 pm 01:03 PM

Ce tutoriel vise à résoudre le problème du chargement des actifs (CSS, JS, images, etc.) lors de l'accès aux URL à plusieurs niveaux (tels que / projets / home) lors du déploiement d'applications (spas) (spas) sur Vercel. Le noyau réside dans la compréhension de la différence entre le mécanisme de réécriture de routage de Vercel et les chemins relatifs / absolus dans HTML. En configurant correctement Vercel.json, assurez-vous que toutes les demandes de non-fichier sont redirigées vers index.html et corriger les références d'actifs dans HTML en tant que chemins absolus, réalisant ainsi le fonctionnement stable du SPA à n'importe quelle URL de profondeur.

Qwik: un cadre de redoppe pour les applications Web à chargement instantané Qwik: un cadre de redoppe pour les applications Web à chargement instantané Aug 15, 2025 am 08:25 AM

QwikachievesInstantLoadingByDefaultthroughroughtumability, Nothydratation: 1) TheServerrendershtmlwithSerializedStateAndpre-MaptEventListeners; 2) norehydratonsneeded, activant la réinteraction; 3) Javascripto

JS Ajouter un élément au début du tableau JS Ajouter un élément au début du tableau Aug 14, 2025 am 11:51 AM

Dans JavaScript, la méthode la plus courante pour ajouter des éléments au début d'un tableau est d'utiliser la méthode Unsich (); 1. En utilisant unsith () modifiera directement le tableau d'origine, vous pouvez ajouter un ou plusieurs éléments pour retourner la nouvelle longueur du tableau ajouté; 2. Si vous ne souhaitez pas modifier le tableau d'origine, il est recommandé d'utiliser l'opérateur d'extension (tel que [Newelement, ... Arr]) pour créer un nouveau tableau; 3. Vous pouvez également utiliser la méthode CONCAT () pour combiner le nouveau tableau d'éléments avec le numéro d'origine, renvoyez le nouveau tableau sans modifier le tableau d'origine; En résumé, utilisez Unsich () lors de la modification du tableau d'origine et recommandez l'opérateur d'extension lorsque vous gardez le tableau d'origine inchangé.

Comment charger des images avec javascript Comment charger des images avec javascript Aug 14, 2025 pm 06:43 PM

Usetheloading = "lazy" attributFornativelazyloadingInModerNBrowsSerswithoutjavascript.2.FormoreControlorolderbrowsSeport, implémentlazyloadingwiththeintesectionobserverapibysettingdata-srcfortheatimagerlandusaplaceholderinsrc.33.obse

Comment accéder et modifier les éléments HTML à l'aide du DOM dans JavaScript Comment accéder et modifier les éléments HTML à l'aide du DOM dans JavaScript Aug 16, 2025 am 11:25 AM

Toaccessandmodifyhtmlelementsusingjavascript, firstSelectTheementUsingMethodslikeDocument.getElementByid, document.queryselect

Analyse approfondie des vulnérabilités communes et des stratégies d'amélioration pour les fonctions de défense JavaScript XSS Analyse approfondie des vulnérabilités communes et des stratégies d'amélioration pour les fonctions de défense JavaScript XSS Aug 14, 2025 pm 10:06 PM

Cet article explore les vulnérabilités de sécurité approfondies dans les fonctions de défense JavaScript XSS JavaScript personnalisées, en particulier l'évasion de caractères incomplète et le contournement facile du filtrage basé sur les mots clés. En analysant un exemple de fonction, il révèle les risques de caractères de mots clés non transformés tels que des citations et des backquotes, et comment les techniques d'obscurcissement du code contournent la détection de mots clés simples. L'article souligne l'importance de l'évasion contextuelle et recommande l'adoption de bibliothèques matures et de stratégies de défense multicouches pour établir une protection de sécurité plus robuste.

Optimiser la gestion des événements des sauts de liaison externe dynamique dans la fenêtre contextuelle jQuery Optimiser la gestion des événements des sauts de liaison externe dynamique dans la fenêtre contextuelle jQuery Sep 01, 2025 am 11:48 AM

Cet article vise à résoudre le problème de la redirection du bouton de redirection de liaison externe dans la fenêtre pop-up jQuery provoquant des erreurs de saut. Lorsqu'un utilisateur clique sur plusieurs liens externes successivement, le bouton Jump dans la fenêtre contextuelle peut toujours pointer vers le premier lien cliqué. La solution principale consiste à utiliser la méthode OFF ('Click') pour annuler l'ancien gestionnaire d'événements avant chaque liaison d'un nouvel événement, garantissant que le comportement de saut pointe toujours vers l'URL cible, réalisant ainsi une redirection de liens précise et contrôlable.

See all articles