본문 바로가기

Javascript

Vanilla JS로 구현한 debounce로 성능 최적화하기

debounce란?

주어진 시간 내에 동일한 이벤트가 반복적으로 시행되는 경우, 마지막 이벤트 발생 후 새로운 이벤트가 발생하지않고 제한 시간이 모두 지나면 해당 이벤트가 실행되도록 하는 이벤트 핸들링 기술. 연이은 이벤트를 하나의 그룹으로 묶어주는 역할을 한다.

 

Vanilla JS로 debounce 구현하기

debounce는 lodash 등의 라이브러리를 사용하면 상대적으로 편리하게 구현할 수 있다.

하지만 그 원리를 알기 위해선 한 번쯤 Vanilla JS로 구현해보는 것이 최고의 방법 🔥

Vanilla JS로 구현한 debounce코드는 아래와 같다.

 

const handleDebounce = (callback, limit) => {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      callback.apply(this, args);
    }, limit);
  };
};

 

  • callback: 실행 대상이 되는 콜백 함수
  • limit: 얼마 후에 callback 함수를 실행할 지 결정하는 제한 시간 (millisecond)

 

실행 순서로 보자면,

  1. handleDebounce 함수 실행
  2. 변수 timeout은 clearTimeout 함수에 의해 초기화
  3. setTimeout에 의해 limit ms이후 callback함수 실행

따라서 limit ms 이내에 callback함수가 호출되면 clearTimeout(timeout)에 의해 실행되지 않고,

마지막 이벤트 발생 후 limit ms가 지나면 setTimeout이 실행되어 callback함수가 실행된다.

 

debounce 활용 예제 - 검색 기능 성능 최적화

개념으로 알아본 debounce를 이제 예제안에서 활용해보자.

debounce가 가장 잘 활용되는 곳은 바로 검색 기능 🔍

가령 input에 텍스트가 입력될 때 이벤트를 추가한다고 하면, 아래와 같이 input에 addEventListener로 keyup이벤트를 추가한다.

debounce 적용 전

코드

// --- debounce를 적용하지않고 addEventListener
input.addEventListener("keyup", () => {
  console.log("search"); //연속적으로 텍스트를 입력하면 입력할 때마다 search 출력
});

 

실행 화면

 

 

텍스트를 연속으로 입력할 때마다 callback함수가 실행되어 console에 search가 찍히게된다.

기능 구현은 되지만 의도한 것보다 이벤트가 불필요하게 많이 실행되어 성능 면에선 아쉬움이 있다.

해결을 위해 아래와 같이 debounce를 적용해보자.

debounce 적용 후

코드

// --- 검색 함수 호출 최적화를 위한 debounce
const handleDebounce = (callback, limit) => {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      callback.apply(this, args);
    }, limit);
  };
};

// --- debounce 적용 후 addEventListener
input.addEventListener(
  "keyup",
  handleDebounce(() => {
    console.log("search");
  }, 500) //연속적으로 텍스트를 입력하더라도 일정시간 이후에 한번만 search 출력
);

 

실행 화면

 

텍스트를 연속해서 작성해도 마지막 작성시점 500ms(0.5초) 후, console에 search가 한 번만 찍히는 걸 볼 수 있다.

 


예제와 같은 검색 기능 외에도 스크롤 이벤트 등 연속된 요청을 보내는 이벤트를 구현할 땐 console을 찍어보면서 무의식적으로 저성능의 구현을 하고있지는 않는지 확인해볼 필요가 있다. 

 

'Javascript' 카테고리의 다른 글

Babel을 활용해 별칭 경로 설정하기  (0) 2022.05.22
실행 컨텍스트와 클로저(Closure)  (0) 2022.04.25
var, let, const의 차이  (0) 2021.11.13
HTML과 Javascript 연결하기  (0) 2021.10.23