keyboard 이벤트, 디바운스(Debounce), 스로틀(Throttle)

keyboard 이벤트, 디바운스(Debounce), 스로틀(Throttle)
홍윤's avatar
Sep 10, 2024
keyboard 이벤트, 디바운스(Debounce), 스로틀(Throttle)
 

1. KeyBoard 이벤트

 
💡
keyboard 이벤트는 사용자가 키보드를 통해 입력할 때 발생하는 이벤트로, 웹 페이지에서 자주 사용하는 중요한 이벤트 중 하나입니다. JavaScript를 이용하여 키보드 이벤트를 처리할 수 있으며, 주로 세 가지 이벤트가 있습니다:
  1. keydown: 키를 눌렀을 때 발생하는 이벤트.
  1. keypress: 키를 눌렀을 때 발생하는 이벤트로, keydown과 비슷하지만 텍스트 입력에 주로 사용됩니다. (최근에는 keypress는 더 이상 사용하지 않는 추세입니다.)
  1. keyup: 키를 눌렀다가 뗄 때 발생하는 이벤트.
다음은 각각의 이벤트를 설명하고, 예제 코드를 통해 이해를 돕겠습니다.

1. keydown 이벤트

  • 설명: 키보드를 눌렀을 때 발생합니다. 어떤 키를 눌렀는지 확인할 수 있습니다.
document.addEventListener('keydown', function(event) { console.log(`Key pressed: ${event.key}`); });
  • event.key: 사용자가 누른 키의 값을 반환합니다. 예를 들어, "a"를 누르면 a가 출력됩니다.
  • 실사용 예: 텍스트 입력 외에 방향키나 특수 키(예: Enter, Shift 등)에 대한 반응을 처리할 때 주로 사용됩니다.

2. keypress 이벤트 (더 이상 권장되지 않음)

  • 설명: 키보드를 눌렀을 때 발생하지만, 주로 문자 입력에 사용됩니다. 현재는 keypress 이벤트는 더 이상 권장되지 않으며, 대신 keydownkeyup 이벤트를 사용하는 것이 좋습니다.
document.addEventListener('keypress', function(event) { console.log(`Key pressed: ${event.key}`); });
  • 이 이벤트는 키보드의 텍스트 입력에 주로 반응하지만, 예를 들어 화살표 키와 같은 제어 키에는 반응하지 않습니다.

3. keyup 이벤트

  • 설명: 사용자가 키를 눌렀다가 뗄 때 발생합니다. 보통 keydown 이벤트와 함께 사용되며, 키 입력 후의 동작을 처리할 때 유용합니다.
document.addEventListener('keyup', function(event) { console.log(`Key released: ${event.key}`); });
  • 실사용 예: 사용자가 키를 뗄 때 실행해야 하는 작업(예: 입력 완료 후의 작업)을 처리할 수 있습니다.

4. event.keyevent.code 차이점

  • event.key: 사용자가 누른 키의 실제 값을 반환합니다. 예를 들어, Shift 키를 누르고 "a"를 눌렀을 때 A가 반환됩니다.
  • event.code: 키보드에서 눌린 물리적 키의 위치를 반환합니다. 예를 들어, 키보드 레이아웃이 다르더라도 동일한 물리적 위치의 키에 대한 코드를 반환합니다.

5. 특정 키 이벤트 처리

특정 키에 대한 이벤트를 처리할 때는 event.keyevent.code를 조건문으로 확인할 수 있습니다.
document.addEventListener('keydown', function(event) { if (event.key === 'Enter') { console.log('Enter key was pressed'); } });
  • 이 코드는 사용자가 Enter 키를 눌렀을 때만 특정 동작을 처리하는 예시입니다.

6. 키보드 이벤트의 추가 속성

  • event.shiftKey: Shift 키가 눌렸는지 여부.
  • event.ctrlKey: Ctrl 키가 눌렸는지 여부.
  • event.altKey: Alt 키가 눌렸는지 여부.
  • event.metaKey: Mac에서 Command 키가 눌렸는지 여부.
document.addEventListener('keydown', function(event) { if (event.ctrlKey && event.key === 's') { event.preventDefault(); // 기본 동작(예: 페이지 저장) 방지 console.log('Ctrl + S was pressed'); } });
  • 이 코드는 사용자가 Ctrl + S를 눌렀을 때 페이지 저장을 방지하고, 대신 커스텀 동작을 실행하는 예시입니다.

요약

  • keydown: 키가 눌리는 순간 발생.
  • keyup: 키가 눌렸다가 놓이는 순간 발생.
  • keypress: 텍스트 입력과 관련된 키가 눌릴 때 발생하지만, 더 이상 권장되지 않음.
이벤트 핸들러를 통해 키보드 이벤트를 감지하고, 사용자가 어떤 키를 입력했는지, 특수 키와 함께 사용했는지 등을 처리할 수 있습니다. event.keyevent.code를 활용해 더 다양한 동작을 제어할 수 있습니다.

 

2. 디바운스(Debounce)

💡
  • 디바운스(Debounce)는 특정 이벤트가 연속적으로 발생할 때, 그 이벤트가 빠르게 여러 번 실행되는 것을 방지하고 일정 시간 동안 이벤트가 발생하지 않을 때에만 마지막 이벤트를 처리하는 기법입니다. 주로 검색창에서 키보드 입력을 처리할 때, 사용자가 입력할 때마다 서버에 요청을 보내지 않도록 하기 위해 자주 사용됩니다.
예를 들어, 사용자가 검색어를 입력할 때 매번 서버에 요청을 보내는 대신, 입력이 멈춘 후 일정 시간(예: 300ms)이 지나야만 요청을 보내도록 하여 성능을 최적화할 수 있습니다.

디바운스 기본 원리

  • 사용자가 입력할 때마다 이벤트가 발생하지만, 이벤트가 발생한 후 일정 시간이 지나면 한 번만 실행됩니다.
  • 이 방식으로 불필요한 서버 요청을 줄이고, 네트워크 트래픽을 절약할 수 있습니다.

디바운스 구현 예시

다음은 자바스크립트에서 디바운스를 구현하는 간단한 예시입니다.
function debounce(func, delay) { let timeout; return function(...args) { clearTimeout(timeout); // 이전 타이머 제거 timeout = setTimeout(() => { func.apply(this, args); // 지정된 시간 후에 함수 실행 }, delay); }; }
debounce 함수는 func(실행할 함수)와 delay(지연 시간)를 인자로 받아서, 디바운싱 처리된 함수를 반환합니다. 입력이 일정 시간 동안 멈출 때만 func 함수가 실행됩니다.

디바운스 사용 예시

위에서 구현한 디바운스를 검색창 이벤트에 적용하는 예시입니다.
// 서버로 요청을 보내는 함수 function searchQuery(query) { console.log(`Searching for: ${query}`); // 서버로 검색 요청을 보낼 수 있습니다. } // 디바운스 적용 (300ms 딜레이) const debouncedSearch = debounce(searchQuery, 300); // 키보드 이벤트 처리 document.getElementById('search-input').addEventListener('keyup', function(e) { debouncedSearch(e.target.value); });

동작 설명

  1. 사용자가 검색창에 글자를 입력할 때마다 keyup 이벤트가 발생합니다.
  1. 이벤트가 발생할 때마다 debouncedSearch 함수가 호출되는데, 이 함수는 300ms 동안 입력이 멈출 때까지 **실제 검색 함수(searchQuery)**의 실행을 지연시킵니다.
  1. 만약 사용자가 300ms 내에 다시 입력을 하면 이전의 타이머가 취소되고 새로운 타이머가 설정됩니다. 결국, 사용자가 입력을 멈춘 후 300ms가 지나야만 서버 요청이 실행됩니다.

디바운스가 필요한 이유

  1. 서버 부하 감소: 연속적으로 빠르게 발생하는 이벤트(예: 키보드 입력)를 처리하지 않고, 일정 시간 후에 한 번만 처리하여 서버 요청 횟수를 줄일 수 있습니다.
  1. 사용자 경험 개선: 지나치게 많은 요청을 방지함으로써, UI가 부드럽고 자연스럽게 동작합니다.

예시: 디바운스를 적용한 검색 기능

<input type="text" id="search-input" placeholder="Search...">
function debounce(func, delay) { let timeout; return function(...args) { clearTimeout(timeout); timeout = setTimeout(() => { func.apply(this, args); }, delay); }; } function searchQuery(query) { console.log(`Searching for: ${query}`); // 여기에 AJAX나 Fetch를 사용하여 서버에 요청을 보낼 수 있습니다. } const debouncedSearch = debounce(searchQuery, 300); document.getElementById('search-input').addEventListener('keyup', function(e) { debouncedSearch(e.target.value); });
위 코드는 사용자가 검색창에 값을 입력할 때마다 서버 요청을 보내지 않고, 입력이 멈추고 300ms 후에 검색을 실행하도록 하는 디바운스 패턴을 적용한 예시입니다.

 

3. 스로틀(Throttle)

💡
  • 스로틀(Throttle)은 디바운스와 유사하지만, 특정 시간 동안 이벤트가 여러 번 발생하더라도 일정한 간격으로 이벤트를 처리하는 기법입니다. 디바운스는 이벤트가 끝난 후에 한 번 실행되는 반면, 스로틀은 일정 시간 간격마다 이벤트를 실행한다는 차이점이 있습니다.
스로틀은 주로 스크롤 이벤트윈도우 리사이즈 이벤트처럼 빠르고 자주 발생하는 이벤트에서, 일정 간격으로만 이벤트 핸들러를 실행해 성능을 최적화할 때 사용됩니다.

스로틀의 주요 목적

  • 이벤트가 매우 빈번하게 발생할 때마다 처리를 하지 않고, 성능을 최적화하기 위해 일정 시간 간격으로만 처리합니다.
  • 서버나 자원에 대한 부하를 줄이는 역할을 합니다.

스로틀 구현 예시

다음은 자바스크립트에서 스로틀을 구현한 간단한 예시입니다.
function throttle(func, limit) { let lastFunc; let lastRan; return function(...args) { const context = this; if (!lastRan) { func.apply(context, args); lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout(function() { if (Date.now() - lastRan >= limit) { func.apply(context, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan)); } }; }
  • func: 실행할 함수.
  • limit: 함수가 실행될 최소 시간 간격(밀리초 단위).
  • lastRan: 마지막으로 함수가 실행된 시간을 기록하여, 일정 시간 간격을 유지합니다.

스로틀 사용 예시

위에서 구현한 스로틀을 스크롤 이벤트에 적용하는 예시입니다.
// 서버로 요청을 보내는 함수 function handleScroll() { console.log('Scroll event handled!'); } // 스로틀 적용 (200ms 간격으로만 실행) const throttledScroll = throttle(handleScroll, 200); // 스크롤 이벤트 처리 window.addEventListener('scroll', throttledScroll);

동작 설명

  1. 사용자가 스크롤을 할 때마다 scroll 이벤트가 발생합니다.
  1. 이벤트가 발생할 때마다 throttledScroll 함수가 호출됩니다. 이 함수는 스로틀에 의해 200ms 간격으로만 실제 handleScroll 함수가 실행됩니다.
  1. 즉, 스크롤이 계속 발생하더라도 200ms마다 한 번씩만 handleScroll 함수가 실행됩니다.

스로틀과 디바운스의 차이점

  1. 디바운스(Debounce):
      • 이벤트가 끝난 후 일정 시간 동안 이벤트가 발생하지 않으면 한 번 실행됩니다.
      • 주로 실시간 검색과 같이 입력이 끝난 후 서버 요청을 처리하는 경우에 사용됩니다.
  1. 스로틀(Throttle):
      • 이벤트가 계속 발생해도 일정한 간격으로 실행됩니다.
      • 주로 스크롤, 리사이즈 이벤트처럼 매우 빈번하게 발생하는 이벤트에서 성능을 최적화할 때 사용됩니다.

예시: 스로틀을 적용한 스크롤 이벤트

<div style="height: 1500px; background-color: lightgrey;"> Scroll to see throttled event in action. </div>
function throttle(func, limit) { let lastFunc; let lastRan; return function(...args) { const context = this; if (!lastRan) { func.apply(context, args); lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout(function() { if (Date.now() - lastRan >= limit) { func.apply(context, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan)); } }; } function handleScroll() { console.log('Scroll event handled at', Date.now()); } const throttledScroll = throttle(handleScroll, 500); window.addEventListener('scroll', throttledScroll);

동작 설명

  1. 사용자가 페이지를 스크롤할 때마다 스크롤 이벤트가 발생하지만, throttledScroll 함수는 500ms마다 한 번씩만 handleScroll 함수를 실행합니다.
  1. 이렇게 하면 스크롤 이벤트가 매우 빠르게 발생하더라도, 불필요한 함수 호출을 방지하고 성능을 최적화할 수 있습니다.

스로틀을 사용하는 이유

  • 빈번한 이벤트 처리 방지: 사용자가 스크롤하거나 창을 리사이즈하는 것처럼 이벤트가 매우 빈번하게 발생할 경우, 이를 모두 처리하지 않고 일정 시간 간격으로만 처리하여 성능을 높일 수 있습니다.
  • UI 성능 최적화: 부드러운 사용자 경험을 유지하면서 리소스 사용을 줄이는 데 도움을 줍니다.

스로틀과 디바운스 비교

  • 디바운스는 연속적인 이벤트가 발생할 때 이벤트가 끝난 후에 한 번 실행됩니다.
  • 스로틀은 연속적인 이벤트가 발생할 때 일정 시간 간격마다 실행됩니다.
이 두 기법은 적절히 사용함으로써 브라우저 성능 최적화에 매우 유용합니다.
Share article

Uni