Entprellen und Drosseln
Eine weitere beliebte Frontend-Interviewfrage. Es testet das Wissen der Befragten zu JS, Leistung und FE-Systemdesign.
Dies ist Frage Nr. 2 der Reihe „Frontend-Interviewfragen“. Wenn Sie Ihre Vorbereitung verbessern oder allgemein auf dem Laufenden bleiben möchten, sollten Sie sich bei FrontendCamp anmelden.
Entprellen und Drosseln funktionieren nach dem gleichen Prinzip – Verzögerungsdinge –, haben aber dennoch sehr unterschiedliche Ansätze und Anwendungsfälle.
Beide Konzepte sind nützlich für die Entwicklung einer leistungsstarken Anwendung. Fast alle Websites, die Sie täglich besuchen, nutzen auf die eine oder andere Weise Entprellen und Drosseln.
Entprellen
Ein bekannter Anwendungsfall des Entprellens ist ein Typeahead (oder eine automatische Vervollständigung).
Stellen Sie sich vor, Sie erstellen eine Suchfunktion für eine E-Commerce-Website mit Tausenden von Produkten. Wenn ein Benutzer versucht, nach etwas zu suchen, führt Ihre App einen API-Aufruf durch, um alle Produkte abzurufen, die mit der Abfragezeichenfolge des Benutzers übereinstimmen.
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} />
Dieser Ansatz sieht gut aus, weist jedoch einige Probleme auf:
- Sie führen bei jedem Tastendruckereignis einen API-Aufruf durch. Wenn ein Benutzer 15 Zeichen eingibt, sind das 15 API-Aufrufe für einen einzelnen Benutzer. Das würde nie skalieren.
- Wenn das Ergebnis dieser 15 API-Aufrufe eintrifft, benötigen Sie nur noch den letzten. Das Ergebnis der vorherigen 14 Aufrufe wird verworfen. Es verbraucht viel Bandbreite des Benutzers und Benutzer in einem langsamen Netzwerk werden eine erhebliche Verzögerung bemerken.
- Auf der Benutzeroberfläche lösen diese 15 API-Aufrufe ein erneutes Rendern aus. Dadurch wird die Komponente verzögert.
Die Lösung für diese Probleme ist Entprellen.
Die Grundidee besteht darin, zu warten, bis der Benutzer mit der Eingabe aufhört. Wir werden den API-Aufruf verzögern.
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)} />
Wir haben unseren bestehenden Code erweitert, um die Entprellung zu nutzen.
Die Debounce-Funktion ist eine generische Hilfsfunktion, die zwei Argumente benötigt:
- fn: Der Funktionsaufruf, der verzögert werden soll.
- Verzögerung: Die Verzögerung in Millisekunden.
Innerhalb der Funktion verwenden wir setTimeout, um den eigentlichen Funktionsaufruf (fn) zu verzögern. Wenn der Fn erneut aufgerufen wird, bevor der Timer abgelaufen ist, wird der Timer zurückgesetzt.
Mit unserer aktualisierten Implementierung würden wir, selbst wenn der Benutzer 15 Zeichen eingibt, nur einen API-Aufruf durchführen (vorausgesetzt, jeder Tastendruck dauert weniger als 500 Millisekunden). Dies löst alle Probleme, die wir hatten, als wir mit der Entwicklung dieser Funktion begannen.
In einer Produktionscodebasis müssen Sie keine eigene Entprellungsdienstprogrammfunktion programmieren. Möglicherweise verwendet Ihr Unternehmen bereits eine JS-Dienstprogrammbibliothek wie lodash, die über diese Methoden verfügt.
Drosselung
Nun, Debounce ist großartig für die Leistung, aber es gibt einige Szenarien, in denen wir nicht x Sekunden warten möchten, bevor wir über eine Änderung benachrichtigt werden.
Stellen Sie sich vor, Sie erstellen einen kollaborativen Arbeitsbereich wie Google Docs oder Figma. Eines der Hauptmerkmale ist, dass ein Benutzer in Echtzeit über Änderungen informiert sein sollte, die andere Benutzer vorgenommen haben.
Bisher kennen wir nur zwei Ansätze:
- Der Noob-Ansatz: Jedes Mal, wenn ein Benutzer seinen Mauszeiger bewegt oder etwas eingibt, führen Sie einen API-Aufruf durch. Sie wissen bereits, wie schlimm es werden kann.
- Der Debounce-Ansatz: Er löst zwar die Leistungsseite, ist aber aus UX-Perspektive schrecklich. Ihr Kollege schreibt möglicherweise einen Absatz mit 300 Wörtern und Sie werden am Ende nur einmal benachrichtigt. Gilt es immer noch als Echtzeit?
Hier kommt Throttling ins Spiel. Es liegt genau in der Mitte der beiden oben genannten Ansätze. Die Grundidee besteht darin, in regelmäßigen Abständen zu benachrichtigen – nicht am Ende und nicht bei jedem Tastendruck, sondern in regelmäßigen Abständen.
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)} />
Wir haben unseren vorhandenen Code geändert, um die Drosselfunktion zu nutzen. Es sind zwei Argumente erforderlich:
- fn: Die eigentliche Funktion zum Drosseln.
- Zeit: Das Intervall, nach dem die Funktion ausgeführt werden darf.
Die Implementierung ist unkompliziert. Den Zeitpunkt des letzten Aufrufs der Funktion speichern wir in lastCalledAt. Wenn das nächste Mal ein Funktionsaufruf erfolgt, prüfen wir, ob die Zeit vergangen ist, und führen erst dann fn.
ausWir haben es fast geschafft, aber diese Implementierung weist einen Fehler auf. Was passiert, wenn der letzte Funktionsaufruf mit einigen Daten innerhalb des Zeitintervalls erfolgt und danach kein Aufruf mehr erfolgt? Bei unserer aktuellen Implementierung gehen einige Daten verloren.
Um dies zu beheben, speichern wir die Argumente in einer anderen Variablen und initiieren eine Zeitüberschreitung, die später aufgerufen wird, wenn kein Ereignis empfangen wird.
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); } } } }
Diese aktualisierte Implementierung stellt sicher, dass uns keine Daten entgehen.
Lodash bietet auch eine Drosselfunktion.
Zusammenfassung
- Entprellen und Drosseln sind Techniken zur Leistungsoptimierung.
- Beide funktionieren nach einem ähnlichen Prinzip – Dinge verzögern.
- Debounce wartet auf t, nachdem das letzte Ereignis empfangen wurde, während Throttling den Fn periodisch in t Zeit ausführt.
- Entprellen wird in Suchfunktionen verwendet und Drosselung wird in Echtzeit-Apps verwendet (nicht darauf beschränkt).
Ressourcen
FrontendCamp
lodash
Das obige ist der detaillierte Inhalt vonEntprellen und Drosseln. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Die erweiterten Bedingungstypen von TypeScript implementieren logische Beurteilung zwischen den Typen über textendu? X: y syntax. Die Kernfähigkeiten spiegeln sich in den verteilten Bedingungstypen, den Abschluss -Inferenz und der Konstruktion komplexer Typ -Werkzeuge wider. 1. Der bedingte Typ ist in den Parametern mit nötigen Typen verteilt und kann den Gelenktyp automatisch aufteilen, z. 2.. Verwenden Sie die Verteilung, um Filter- und Extraktionsinstrumente zu erstellen: Ausschließen Typen über Textendsu? Nie: t, extrahieren Gemeinsamkeiten durch textendu? 3

MicrofrontendsolvescalingchalenGesinlargeamsByenablingIndependentDevelopment und Deployment.1) ChooseanintegrationStrategy: Usemodulefederationsinwebpack5forruntImeloadingandtrueIndependenz, Bauzeitintegrationslimplations-, Orifrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/Webrahmen/webkConponents

VariFrention-Scoped, Canberase signiert, mitgeheizt, und erreicht, und antachedtotheglobalWindowObject; 2. LetandConstareblock-scoped, withletAllowingReassignmentandConstnotallowingit, aberConstobjectscanhavemuthingProperties;

In diesem Artikel wird eingehend untersucht, wie man automatisch lösbare Rätsel für das Doppel-Choco-Puzzlespiel generiert. Wir werden eine effiziente Datenstruktur einführen - ein Zellobjekt basierend auf einem 2D -Gitter, das Grenzinformationen, Farbe und Zustand enthält. Auf dieser Basis werden wir einen rekursiven Blockerkennungsalgorithmus (ähnlich wie bei der Tiefe-First-Suche) und der Integration in den iterativen Puzzle-Erzeugungsprozess eingehen, um sicherzustellen, dass die erzeugten Rätsel den Spielregeln entsprechen und fehlerhaft sind. Der Artikel bietet Beispielcode und diskutiert wichtige Überlegungen und Optimierungsstrategien im Erzeugungsprozess.

Die häufigste und empfohlene Methode zum Entfernen von CSS -Klassen aus DOM -Elementen unter Verwendung von JavaScript ist die Methode von REME () der Classlist -Eigenschaft. 1. Verwenden Sie Element.ClassList.remove ('className'), um einen einzelnen oder mehrere Klassen sicher zu löschen, und es wird kein Fehler gemeldet, selbst wenn die Klasse nicht vorhanden ist. 2. Die alternative Methode besteht darin, die Eigenschaft der Klassenname direkt zu bedienen und die Klasse mit einem String -Austausch zu entfernen. Aufgrund der ungenauen regelmäßigen Übereinstimmung oder einer unsachgemäßen Raumverarbeitung ist es jedoch einfach, Probleme zu verursachen, sodass sie nicht empfohlen wird. 3. Sie können zuerst beurteilen, ob die Klasse existiert, und sie dann durch Element.ClassList.Contains () löschen, aber es ist normalerweise nicht erforderlich. 4. Classlist

Die Klassensyntax von JavaScript ist syntaktischer Zucker, die durch Prototypen geerbt wurden. 1. Die von der Klasse definierte Klasse ist im Wesentlichen eine Funktion und Methoden werden dem Prototyp hinzugefügt. 2. Die Instanzen suchen Methoden durch die Prototypkette; 3. Die statische Methode gehört zur Klasse selbst; 4. Erweitert die Erbringe durch die Prototypkette, und die zugrunde liegende Schicht verwendet immer noch den Prototypmechanismus. Die Klasse hat die Essenz des JavaScript -Prototyps -Vererbung nicht verändert.

Dieser Artikel soll das Problem der tiefen URL -Aktualisierung oder des direkten Zugriffs lösen, wodurch die Seitungsressourcenladefehler bei der Bereitstellung von Einzelseiten -Anwendungen (SPAs) auf Vercel verursacht wird. Der Kern besteht darin, den Unterschied zwischen dem Routing -Umschreibmechanismus von Vercel und dem Parsen von Browser -Parsen relative Pfade zu verstehen. Durch die Konfiguration von Vercel.json, um alle Pfade zu index.html umzuleiten und die Referenzmethode der statischen Ressourcen in HTML zu korrigieren, ändern Sie den relativen Pfad in den absoluten Pfad, um sicherzustellen, dass die Anwendung alle Ressourcen korrekt unter eine URL laden kann.

Die Array -Methoden von JavaScript, Filter und Reduzierung von Array -Methoden werden zum Schreiben von klaren und funktionalen Code verwendet. 1. MAP wird verwendet, um jedes Element in das Array umzuwandeln und ein neues Array zurückzugeben, z. B. Celsius in Fahrenheit umzuwandeln. 2. Filter wird verwendet, um Elemente gemäß den Bedingungen zu filtern und ein neues Array zurückzugeben, das den Bedingungen entspricht, z. B. auch Zahlen oder aktive Benutzer; 3. Reduzierung wird verwendet, um Ergebnisse wie das Summieren oder Zählen der Frequenz zu sammeln, und der Anfangswert muss bereitgestellt und an den Akkumulator zurückgegeben werden. Keiner der drei modifiziert das ursprüngliche Array und kann in der Kette aufgerufen werden, die für die Datenverarbeitung und -konvertierung geeignet ist und die Code -Lesbarkeit und -funktionalität verbessert.
