Github 코드 저장소
빠르게 변화하는 세상에서 우리가 하는 대부분의 작업은 웹에서 빠르게 이루어집니다. 원활하고 원활한 사용자 경험을 만드는 것이 더욱 중요해졌습니다. 소비자는 지연이나 지연 없이 빠르게 작동하는 UI를 좋아합니다. 비록 까다롭기는 하지만 거의 완벽한 경험을 달성하는 것은 가능합니다. 이벤트 루프(Event Loop)에 대해 들어보셨나요?
JavaScript에서 이벤트 루프는 코드 실행 순서를 관리하고, 프로세스를 수집하고, 대기열에 있는 하위 작업에 명령을 넣고, 비동기 작업을 효율적으로 실행하는 기본 개념입니다. 이벤트 루프 작동 방식에 대한 간략한 설명은 다음과 같습니다.
이 이벤트 루프는 호출 스택을 지속적으로 확인합니다. 호출 스택이 빌 때까지 JavaScript 코드 실행이 계속됩니다.
이벤트 처리는 JavaScript 애플리케이션 구축에 있어 매우 중요한 부분입니다. 이러한 애플리케이션에서는 여러 이벤트를 UI 구성 요소와 연결해야 할 수도 있습니다.
UI에는 최신 스포츠 뉴스로 테이블을 채우는 데 도움이 되는 버튼이 있습니다. 이제 다음이 필요합니다.
이 3가지 프로세스는 동기식으로 함께 연결됩니다. 이제 버튼을 반복적으로 누르면 여러 API 호출이 발생하여 UI가 몇 초 동안 차단되어 사용자 경험이 느려지는 것처럼 보입니다.
이는 디바운싱 및 제한과 같은 접근 방식에 대한 좋은 사용 사례입니다. 복잡한 이벤트 체인을 트리거하는 이와 같은 이벤트의 경우 이러한 조작을 사용하여 API를 호출하는 횟수를 제한하거나 일반적인 의미에서 이벤트를 처리하는 속도를 제한할 수 있습니다.
디바운싱: 마지막 이벤트 이후 지정된 대기 시간이 경과할 때까지 함수 실행을 연기합니다.
예:
2초 동안 handlerOnPressKey()를 디바운스하면 사용자가 2초 동안 키 누르기를 중지한 경우에만 실행됩니다.
코드 조각:
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);
제한: 이벤트 발생 빈도에 관계없이 지정된 기간 내에 함수가 최대 한 번 호출되도록 보장합니다.
예:
2초 간격으로 handlerOnScroll()을 조절하면 해당 기간 내에 스크롤 이벤트가 여러 번 트리거되더라도 함수는 최대 2초마다 한 번씩 실행됩니다.
코드 예:
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);
더 중요한 script.js로 넘어가기 전에 HTML 코드를 빠르게 살펴보겠습니다
빠른 스타일링을 위해 TailwindCSS를 사용했습니다. 여기에서 해당 문서를 확인할 수 있습니다. Tailwind 문서 - 빠른 프로토타입을 만드는 데 큰 도움이 됩니다
<!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;
이 섹션에서는 작업 배열을 초기화하고 Fuse.js, 디바운스 타이머 및 스로틀 타이머에 대한 변수를 선언합니다. 우리는 이 프로젝트를 위해 이미 일부 작업을 하드코딩했습니다
이제 onSubmit 함수를 빌드해 보겠습니다. 이 기능은 사용자가 제출 화살표를 클릭하면 실행됩니다. 기본 양식 제출을 방지하고, 입력 값을 검색하고, 입력 필드를 지우고, 작업 배열에 새 작업을 추가하고, 작업 목록을 업데이트합니다.
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);
이제 제출된 작업이 작업 목록에서 업데이트되는지 확인해야 합니다
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);
updateList() 함수는 작업 배열을 반복하고 각 작업에 대한 목록 항목을 생성하여 작업 목록을 렌더링합니다. 각 목록 항목에는 글머리 기호와 작업 텍스트가 포함되어 있습니다.
이제 페이지가 처음 로드된 후 목록이 업데이트되는지 확인해야 합니다. 또한 페이지 로드 시 Fuse.js를 초기화하고 작업 배열을 이에 연결하려고 합니다. 드롭다운 내에서 이 작업 배열의 제안을 렌더링해야 한다는 점을 기억하세요.
<!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(); }
이제 모든 '입력'에 대해 목록을 검색하여 드롭다운에 제안 사항이 표시되도록 해야 합니다. 이는 세 부분으로 구성됩니다:
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);
지금까지: 뭔가를 입력할 때마다 드롭다운 목록이 업데이트됩니다. 더 큰 UI에서는 이러한 경험을 원하지 않습니다
큰 UI에서 키를 누를 때마다 드롭다운 목록을 업데이트하면 성능 문제가 발생하여 지연이 발생하고 사용자 경험이 저하될 수 있습니다. 빈번한 업데이트는 이벤트 루프에 부담을 주어 다른 작업 처리가 지연될 수 있습니다.
이제 디바운싱 또는 제한을 사용하여 업데이트 빈도를 관리하고 보다 원활한 성능과 응답성이 뛰어난 인터페이스를 보장하는 방법을 살펴보겠습니다.
노트 작성 프로젝트에서 기술 중 하나를 구현하는 방법은 다음과 같습니다.
디바운싱은 마지막 호출 이후 지정된 시간이 경과한 후에만 함수가 호출되도록 보장합니다. 이는 API 호출을 하기 전에 사용자가 입력을 마칠 때까지 기다리려는 검색 입력 필드와 같은 시나리오에 유용합니다.
코드 조각:
//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); }
설명:
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"; }
설명:
그러나 참고: 조절은 함수 실행 빈도를 고정된 간격으로 제한하여 실시간 검색 제안에 대한 최상의 사용자 경험을 제공하지 못할 수 있으므로 이 시나리오에 가장 적합하지 않습니다. 사용자는 입력할 때 즉각적인 피드백을 기대하며 제한으로 인해 눈에 띄는 지연이 발생할 수 있습니다.
제한은 성능 문제를 방지하기 위해 이벤트 처리 속도를 제어하려는 시나리오에 더 적합합니다. 다음은 몇 가지 예입니다.
이러한 시나리오에서 제한을 사용하면 성능을 향상하고 보다 원활한 사용자 경험을 보장할 수 있습니다.
여기에서 전체 코드를 찾으세요
즐거운 코딩하세요!
의견을 남겨주세요!
이 블로그가 도움이 되었기를 바랍니다! 여러분의 피드백은 저에게 매우 소중합니다. 아래 댓글에 여러분의 생각과 제안을 남겨주세요.
더 많은 통찰력과 업데이트를 원하시면 언제든지 LinkedIn에서 저와 연락해 주세요. 계속 연결되어 함께 배우고 성장해 나가세요!
위 내용은 Smooth UX의 기술: 보다 성능이 뛰어난 UI를 위한 디바운싱 및 조절의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!