디바운스&쓰로틀

kimminjunnn·2025년 5월 19일

CS

목록 보기
21/34

이벤트가 과도하게 호출되어 성능에 문제를 일으킬 경우 해결 방법

브라우저 이벤트 중 scroll, resize, input, mousemove 등은 초당 수십~수백 회 발생할 수 있다.
이 때 콜백 함수가 너무 자주 실행되면 렌더링 지연, CPU 과부하 등 성능 저하가 발생할 수 있다.


해결 방법

1. 디바운스(Debounce)

  • 연속된 이벤트 중, 마지막 이벤트 발생 후 일정 시간 지나면 실행
  • 입력이 멈췄을 때만 실행하고 싶을 때 사용
function debounce(fn, delay) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

apply는 this를 지정하고, 인자를 배열 형태로 전달할 수 있게 해주는 메서드

예시

function onSearchInput(e) {
  console.log('검색어:', e.target.value);
}

const debouncedSearch = debounce(onSearchInput, 500);
document.getElementById('search').addEventListener('input', debouncedSearch);

사용자가 키보드를 계속 누를 때마다 이전 타이머는 취소됨
입력이 멈춘 후 500ms가 지나야만 onSearchInput이 실행됨

2. 쓰로틀(Throttle)

  • 이벤트가 반복되어도, 일정 간격으로만 실행
  • 스크롤 추적처럼 지속적이고 반복적인 실행이 필요할 때 사용
function throttle(fn, delay) {
  let lastCall = 0; //마지막으로 fn이 실행된 시간을 저장할 변수

  return function (...args) {
    const now = Date.now();
    if (now - lastCall >= delay)  { 
// 지금 시점에서 마지막 실행 시점(lastCall)을 뺀 값이 delay 이상이면 실행 가능이라는 조건
      lastCall = now;
      fn.apply(this, args); 
    }
  };
}

언제 쓰나?

  • 무한 스크롤
  • 마우스 움직임 추적
  • 윈도우 리사이즈 등
    → 사용자가 빠르게 이벤트를 연속적으로 발생시키더라도 일정 주기로만 실행

예시

function onScroll(e) {
  console.log('스크롤 중...', e);
}

window.addEventListener('scroll', throttle(onScroll, 200));

-> 최소 200ms 간격으로 한번씩만 실행되도록 제한되고 있기 때문에 최대 초당 5번까지만 실행됨

profile
Frontend Engineers

0개의 댓글