Github-Code-Repository
In der schnelllebigen Welt finden die meisten Jobs, die wir erledigen, im Internet statt, und zwar schnell. Umso wichtiger wird es, ein nahtloses und reibungsloses Benutzererlebnis zu schaffen. Verbraucher lieben eine Benutzeroberfläche, die schnell und ohne Verzögerungen funktioniert. Es ist möglich, wenn auch schwierig, ein nahezu perfektes Erlebnis zu erreichen. Haben Sie schon einmal von Event Loops gehört?
In JavaScript ist die Ereignisschleife ein grundlegendes Konzept, das die Reihenfolge der Codeausführung verwaltet, Prozesse sammelt, Anweisungen in Unteraufgaben in der Warteschlange platziert und asynchrone Vorgänge effizient ausführt. Hier ist eine kurze Aufschlüsselung der Funktionsweise einer Ereignisschleife:
Diese Ereignisschleife überprüft kontinuierlich den Aufrufstapel. Die Ausführung eines JavaScript-Codes wird fortgesetzt, bis der Aufrufstapel leer ist.
Die Ereignisbehandlung ist ein sehr wichtiger Teil beim Erstellen von JavaScript-Anwendungen. In einer solchen Anwendung müssen wir möglicherweise mehrere Ereignisse einer UI-Komponente zuordnen.
Sie haben eine Schaltfläche in einer Benutzeroberfläche, die dabei hilft, eine Tabelle mit den neuesten Nachrichten zum Thema Sport zu füllen. Dazu müssen Sie Folgendes tun:
Diese 3 Prozesse sind synchron miteinander verkettet. Nun würde ein wiederholtes Drücken der Schaltfläche mehrere API-Aufrufe bedeuten – was dazu führen würde, dass die Benutzeroberfläche für einige Sekunden blockiert wird – eine scheinbar verzögerte Benutzererfahrung.
Dies ist ein guter Anwendungsfall für Ansätze wie Entprellen und Drosseln. Bei Ereignissen wie diesem, die eine Kette komplexer Ereignisse auslösen, können wir solche Manöver verwenden, um die Anzahl der Aufrufe der API zu begrenzen, oder im Allgemeinen die Geschwindigkeit zu begrenzen, mit der wir ein Ereignis verarbeiten.
Entprellen:Verzögern der Ausführung einer Funktion, bis eine bestimmte Abklingzeit seit dem letzten Ereignis verstrichen ist.
Zum Beispiel:
Wenn wir handleOnPressKey() für 2 Sekunden entprellen, wird es nur ausgeführt, wenn der Benutzer für 2 Sekunden keine Tasten mehr drückt.
Codeausschnitt:
let debounceTimer; // Timer reference const handleOnPressKey = () => { console.log("Key pressed and debounce period elapsed!"); }; const debouncedKeyPress = () => { // Clear any existing timer clearTimeout(debounceTimer); // Start a new debounce timer debounceTimer = setTimeout(() => { handleOnPressKey(); // Execute the function after cooldown }, 2000); // Cooldown period of 2000ms }; // Attach debouncedKeyPress to keypress events document.getElementById("input").addEventListener("keypress", debouncedKeyPress);
Drosselung: Sicherstellen, dass eine Funktion höchstens einmal innerhalb eines bestimmten Zeitraums aufgerufen wird, unabhängig davon, wie oft das Ereignis auftritt.
Zum Beispiel:
Wenn wir handleOnScroll() mit einem 2-Sekunden-Intervall drosseln, wird die Funktion höchstens einmal alle 2 Sekunden ausgeführt, auch wenn das Scroll-Ereignis innerhalb dieses Zeitraums mehrmals ausgelöst wird.
Codebeispiel:
let throttleTimer; // Timer reference const handleOnScroll = () => { console.log("Scroll event processed!"); }; const throttledScroll = () => { if (!throttleTimer) { handleOnScroll(); // Execute the function immediately throttleTimer = setTimeout(() => { throttleTimer = null; // Reset timer after cooldown }, 2000); // Cooldown period of 2000ms } }; // Attach throttledScroll to scroll events document.addEventListener("scroll", throttledScroll);
Werfen wir kurz einen Blick auf den HTML-Code, bevor wir uns dem kritischeren script.js zuwenden
Wir haben TailwindCSS für schnelles Styling verwendet. Sie können ihre Dokumentation hier einsehen: Tailwind Documentation – sie ist enorm hilfreich für die Erstellung schneller Prototypen
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Event Loop Practice</title> <!-- Tailwind CSS CDN --> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <style> /* Tailwind Extensions (Optional for Customizations) */ body { font-family: 'Inter', sans-serif; } </style> </head> <body> <h3> Why Use Fuse.js? </h3> <p>Fuse.js is a lightweight, customizable library for fuzzy searching. It handles typos and partial matches, offers high performance for large datasets, and has an intuitive API. This will help enhance your search functionality with flexible, user-friendly search experiences. Additionally, this provides you with a CDN link, so it can work right of the bat, no imports or local storage required.</p> <h2>Now let's Code in the Real Deal - The JS</h2> <h4> 1. Task Array and Variables </h4> <pre class="brush:php;toolbar:false">const tasks = new Array ( "Complete Blog on Throttling + Debouncing", "Make a list of 2025 Resolutions", ); let fuse = undefined; let debounceTimer; let throttleTimer;
In diesem Abschnitt wird eine Reihe von Aufgaben initialisiert und Variablen für Fuse.js, den Debounce-Timer und den Throttle-Timer deklariert. Wir haben einige Aufgaben bereits fest codiert – für dieses Projekt
Jetzt bauen wir die onSubmit-Funktion auf. Diese Funktion wird ausgelöst, sobald der Benutzer auf den Senden-Pfeil klickt. Es verhindert die standardmäßige Formularübermittlung, ruft den Eingabewert ab, löscht das Eingabefeld, fügt die neue Aufgabe zum Aufgabenarray hinzu und aktualisiert die Aufgabenliste.
let debounceTimer; // Timer reference const handleOnPressKey = () => { console.log("Key pressed and debounce period elapsed!"); }; const debouncedKeyPress = () => { // Clear any existing timer clearTimeout(debounceTimer); // Start a new debounce timer debounceTimer = setTimeout(() => { handleOnPressKey(); // Execute the function after cooldown }, 2000); // Cooldown period of 2000ms }; // Attach debouncedKeyPress to keypress events document.getElementById("input").addEventListener("keypress", debouncedKeyPress);
Jetzt müssen wir sicherstellen, dass eine einmal übermittelte Aufgabe in der Aufgabenliste aktualisiert wird
let throttleTimer; // Timer reference const handleOnScroll = () => { console.log("Scroll event processed!"); }; const throttledScroll = () => { if (!throttleTimer) { handleOnScroll(); // Execute the function immediately throttleTimer = setTimeout(() => { throttleTimer = null; // Reset timer after cooldown }, 2000); // Cooldown period of 2000ms } }; // Attach throttledScroll to scroll events document.addEventListener("scroll", throttledScroll);
Die Funktion updateList() rendert die Aufgabenliste, indem sie das Aufgabenarray durchläuft und Listenelemente für jede Aufgabe erstellt. Jedes Listenelement enthält einen Aufzählungspunkt und den Aufgabentext.
Jetzt müssen wir sicherstellen, dass die Liste nach dem ersten Laden der Seite aktualisiert wird. Wir möchten auch Fuse.js beim Laden der Seite initialisieren – und das Aufgabenarray damit verknüpfen. Denken Sie daran, dass wir Vorschläge aus diesem Aufgabenarray im Dropdown-Menü darstellen möchten.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Event Loop Practice</title> <!-- Tailwind CSS CDN --> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <style> /* Tailwind Extensions (Optional for Customizations) */ body { font-family: 'Inter', sans-serif; } </style> </head> <body> <h3> Why Use Fuse.js? </h3> <p>Fuse.js is a lightweight, customizable library for fuzzy searching. It handles typos and partial matches, offers high performance for large datasets, and has an intuitive API. This will help enhance your search functionality with flexible, user-friendly search experiences. Additionally, this provides you with a CDN link, so it can work right of the bat, no imports or local storage required.</p> <h2>Now let's Code in the Real Deal - The JS</h2> <h4> 1. Task Array and Variables </h4> <pre class="brush:php;toolbar:false">const tasks = new Array ( "Complete Blog on Throttling + Debouncing", "Make a list of 2025 Resolutions", ); let fuse = undefined; let debounceTimer; let throttleTimer;
const onSubmit = (event) => { //Prevent default event.preventDefault(); const text = document.getElementById("input").value.trim(); document.getElementById("input").value = ""; tasks.push(text); updateList(); }
Jetzt müssen wir sicherstellen, dass wir bei jeder „Eingabe“ die Liste durchsuchen, um Vorschläge im Dropdown anzuzeigen. Dies besteht aus 3 Teilen:
const updateList = () => { const lists = document.getElementById("taskList"); lists.innerHTML = ""; //Loop through all elements in tasks tasks.forEach(task => { const taskElement = document.createElement("li"); taskElement.classList.add("flex", "items-center", "space-x-2"); //Add Bullet Point Element const bullet = document.createElement("span"); bullet.classList.add("h-2", "w-2", "bg-blue-500", "rounded-full"); //Add Span Tag const taskText = document.createElement("span"); taskText.textContent = task; taskElement.appendChild(bullet); taskElement.appendChild(taskText); lists.appendChild(taskElement); }) }
const init = () => { console.log("Initializing..."); //Update and render the list updateList(); //Initialize Fuse with the updated array try{ fuse = new Fuse(tasks, { includeScore: true, threshold: 0.3 //For sensitivity }) } catch(e) { console.log("Error initializing Fuse:"+ fuse); } }
document.addEventListener("DOMContentLoaded", init);
Bisher: Die Dropdown-Liste wird jedes Mal aktualisiert, wenn Sie etwas eingeben – in einer umfangreicheren Benutzeroberfläche würden wir dieses Erlebnis nicht wollen
Das Aktualisieren der Dropdown-Liste bei jedem Tastendruck in einer umfangreichen Benutzeroberfläche kann zu Leistungsproblemen führen, was zu Verzögerungen und einer schlechten Benutzererfahrung führt. Häufige Aktualisierungen können die Ereignisschleife überfordern und zu Verzögerungen bei der Verarbeitung anderer Aufgaben führen.
Wir werden nun sehen, wie wir mithilfe von Entprellen ODER Drosseln die Aktualisierungshäufigkeit verwalten und so eine reibungslosere Leistung und eine reaktionsfähigere Benutzeroberfläche gewährleisten können.
So können wir beide Techniken in unserem Notizenprojekt implementieren.
Entprellen stellt sicher, dass eine Funktion erst aufgerufen wird, nachdem seit dem letzten Aufruf eine bestimmte Zeitspanne vergangen ist. Dies ist nützlich für Szenarien wie Sucheingabefelder, bei denen wir warten möchten, bis der Benutzer mit der Eingabe fertig ist, bevor wir einen API-Aufruf tätigen.
Code-Snippet:
//Utility function to search within already entered values const searchTasks = (query) => { const result = fuse.search(query); const filteredTasks = result.map(result => result.item) updateDropdown(filteredTasks); }
Erklärung:
const updateDropdown = (tasks) => { const dropdown = document.getElementById("dropdown"); dropdown.innerHTML = ""; if(tasks.length === 0) { dropdown.style.display = "none"; return; } tasks.forEach(task => { const listItem = document.createElement("li"); listItem.textContent = task; listItem.addEventListener("click", () => { document.getElementById("input").value = task; dropdown.style.display = "none"; }) dropdown.appendChild(listItem); }); dropdown.style.display = "block"; }
Erklärung:
Bitte beachten Sie jedoch: Drosselung ist für dieses Szenario nicht die beste Lösung, da sie die Häufigkeit der Funktionsausführung auf ein festes Intervall begrenzt, was möglicherweise nicht die beste Benutzererfahrung für Echtzeit-Suchvorschläge bietet. Benutzer erwarten während der Eingabe eine sofortige Rückmeldung, und die Drosselung kann zu spürbaren Verzögerungen führen.
Drosselung eignet sich besser für Szenarien, in denen Sie die Geschwindigkeit der Ereignisverarbeitung steuern möchten, um Leistungsprobleme zu vermeiden. Hier einige Beispiele:
Durch die Verwendung der Drosselung in diesen Szenarien können Sie die Leistung verbessern und ein reibungsloseres Benutzererlebnis gewährleisten.
Den vollständigen Code finden Sie hier
Viel Spaß beim Codieren!
Bitte hinterlassen Sie ein Feedback!
Ich hoffe, Sie fanden diesen Blog hilfreich! Ihr Feedback ist für mich von unschätzbarem Wert. Bitte hinterlassen Sie Ihre Gedanken und Vorschläge in den Kommentaren unten.
Vernetzen Sie sich gerne mit mir auf LinkedIn, um weitere Einblicke und Updates zu erhalten. Bleiben wir in Verbindung und lernen und wachsen wir gemeinsam weiter!
Das obige ist der detaillierte Inhalt vonDie Kunst von Smooth UX: Entprellen und Drosseln für eine leistungsfähigere Benutzeroberfläche. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!