티스토리 뷰

반응형

디바운싱(debouncing)은 연속으로 호출되는 함수들 중에 마지막 함수만 호출되도록 하는 것이다. 웹 이벤트를 제어하는 방법 중 하나로 쓰로틀링(throttling)과 많이 나오는 개념 중 하나이다. 디바운싱의 예로 가장 많이 나오는 것은 웹 페이지의 스크롤이라고 할 수 있다. 웹 페이지 스크롤을 하면 연속적인 동작이다. 이러한 연속적인 동작에서 마지막에 호출되는 함수만 사용할 수 있도록 만드는 것이 디바운싱이라고 할 수 있다. input과 관련된 디바운싱 예시, 스크롤과 관련된 디바운싱 예시, react에서 hook으로 사용되는 디바운싱 예시도 담았다. 아래의 내용을 통해 디바운싱에 대한 이해도를 높여보자.

 

 

 

디바운싱

디바운싱은 따로 함수가 존재해서 코드 하나로 사용할 수 있는것은 아니다. 즉, 프로그램 기법으로 이해하면 좋다. 연속으로 발생하는 함수를 묶어서 마지막에 한 번만 실행하는 게 디바운싱이다. 연속으로 발생하는 함수를 무시하기 위해 setTimeout를 사용하여 구현한다. 우선은 브라우저가 제공하는 web API인 setTimeout 대해 알아보자.

 

setTimeout(callbackFunction, timeout)

 

  • timeout은 함수가 시작되기 전 대기하는 밀리터리 초이다. 1000을 적으면 1초 후에 콜백함수가 실행한다는 이야기이다.
  • callbackFunction은 함수가 timeout 이후에 실행되는 함수명이다.

 

여기서 우리는 조금 더 알아야하는 web API가 있다. 바로 clearTimeout이다. 

 

clearTimeout(timeoutID)

 

timeoutID는 식별자로 setTimeout()에서 반환된 값을 timeoutID로 담아서 넣어주는 것이라 생각하면 된다. 자세한 예는 아래의 예에서 확인하자.

 

 

디바운싱 예제

input 태그

input 검책 태그에 글을 작성 시,  0.3 초마다 검색 결과 이벤트를 발생시키는 디바운싱 예제는 아래와 같다. 대부분 블로그에서 아래의 예를 보여준다. 아래의 예에서 디바운싱의 이해를 조금 더 높일 수 있다.

 

// html
<input type="text" id="debouncing" />

// javascript
const inputElement = document.querySelector('#debouncing')

const handleInputChange = () => {
  console.log('검색!');
}

let timerId;

inputElement.addEventListener('input', () => {
  if (timerId) clearTimeout(timerId);
  timerId = setTimeout(handleInputChange, 300)
})

 

글 작성 시 timerId에 값이 있다면, setTimeout의 콜백함수를 진행하기전에 0.3초를 기다리고 있는 상태이다. 따라서 clearTimeout으로 timerId가 들어가서 기다리던 콜백함수가 취소된다. 즉, 0.3 초가 지나기 전에 검색창을 입력하면, 이전에 실행된 setTimeout은 취소되고 앞으로 의 새로운 setTimeout이 실행되는 것이다. 이러한 로직을 통해 0.3초 내에 반복되는 중복 실행을 방지한다.

 

아래와 같이 위의 내용을 조금 더 업그레이드 해보겠다.

 

input 태그 적용

// html
<input type="text" id="debouncing" />
<div id="values"></div>

// javascript
const inputElement = document.querySelector('#debouncing')
const devElement = document.getElementById('values');


const handleInputChange = () => {
  devElement.textContent = e.target.value
}

let timerId;

inputElement.addEventListener('input', () => {
  if (timerId) clearTimeout(timerId);
  timerId = setTimeout(handleInputChange, 300)
})

 

적은 내용들을 0.3초마다 최신화하여 업데이트하는 내용이다. 조금 더 예시를 더 보자. 스크롤 관련된 디바운싱 적용한 예시는 아래와 같다.

 

let timer;

const handleScroll = () => {
    const scrollValue = document.documentElement.scrollTop;
    console.log(scrollValue);
}

document.addEventListener("scroll", () => {   
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => handleScroll, 300);
})

 

사실 예시들이 비슷하다. 이러한 예시들을 통해 앞으로 디바운신이 필요하다면, 적용해서 사용하면 된다. 

 

 

React 디바운싱 Hook

 

React Hook으로 만들어서 필요시 쉽게 불러와서 사용가능하도록 만들어 보자.

import { useCallback, useEffect } from 'react';

const useDebounce = (func, delay, deps) => {
  const callback = useCallback(func, deps);
  useEffect(() => {
    const timer = setTimeout(() => callback(), delay);
    return () => clearTimeout(timer);
  }, [callback, delay]);
};

export default useDebounce;

 

 

만약 유료 API를 사용하는 상황이라면, 디바운싱을 활용하며, 여러 번 호출을 방지하여 API를 막을 수 있다. 서비스 제작 중이라면, 디바운싱을 적용하는 것에 대해 한번 고민을 해보면 좋을 것 같다.

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함