티스토리 뷰

WEB/Javascript

쓰로틀링과 디바운싱

이지홍 2022. 12. 27. 01:33
반응형

디바운싱과 쓰로틀링 둘은 모두 웹에서 발생하는 이벤트를 제어하는 방법이다. 

예를 들어 스크롤 이벤트의 경우 스크롤링 할 때마다 발생하는데, 그 때마다 같은 작업을 실행하게 되면 성능 문제가 발생할 수 있다. 
디바운스와 쓰로틀링을 적절한 상황에서 사용하여 이러한 성능상의 이슈를 막을 수 있다.

 

📍 디바운싱 (Debouncing)

연속으로 호출되는 함수들 중에 마지막에 호출되는 함수(또는 제일 처음 함수)만 실행되도록 하는 것


예를 들어 검색 버튼을 누르지 않아도 사용자가 입력한 값이 변경될 때마다 자동으로 검색 요청을 보내는 기능을 만든다고 한다면, 사용자가 입력하는 value 값 마다 계속해서 요청이 보내지게 되므로 비효율적이다. 

이러한 경우에 디바운싱을 적용하면 사용자의 입력이 끝나고 일정 시간이 지난 후에 검색 요청이 1번만 보내지므로 성능을 향상시킬 수 있다. 

디바운싱을 코드로 표현하자면 다음과 같다. 

const inputElement = document.querySelector('#ID값');
const DELAY = 500;
const handleChange = () => {
  console.log('요청!');
}

let timer;

inputElement.addEventListener('input', () => {
  if (timer) clearTimeout(timer);
  timer = setTimeout(handleChange, DELAY);
});

디바운싱을 구현하기 위해서는 SetTimeout함수와 time(기준시간)이 필요하다. 

이벤트가 발생할 때마다 timer 변수에 콜백 함수를 반환하는 seTimeout 함수를 값으로 할당한다. 
time 이내에 새로운 이벤트가 발생할 때마다 타이머를 초기화해준다고 이해하면 된다. 

time 이내에 새로운 이벤트가 발생한다면 clearTimeout을 해줌으로써 콜백함수는 실행되지 않으며, 발생하지 않으면 setTimeout은 콜백함수를 실행하게 된다. 

 

리액트에서는 다음과 같이 함수 실행에 디바운싱을 적용한 커스텀 훅을 만들어 사용할 수도 있다. 

import { useCallback, useEffect } from 'react';

const useDebounceFunc = (func: () => void, delay: number, deps: any[]) => {
  const callback = useCallback(func, deps);

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

export default useDebounceFunc;

 

📍 쓰로틀링(throttling)

마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것


직역하면 조절 혹은 목을 조른다는 뜻으로, 주로 PC나 하드웨어의 성능 제한과 관련해 많이 사용되는 개념이다. 

자바스크립트에서의 쓰로틀링은 짧은 시간 내에 과도한 이벤트 실행으로 인해 발생하는 성능 저하를 막기 위해 일정한 time slice를 주기로 이벤트가 한 번만 실행되도록 제한한다. 

예를 들어 1초에 100번의 업데이트가 일어나는 DOM 요소에 이벤트 핸들러를 추가한다면, 이벤트는 1초에 100번이나 실행되므로 성능에 무리를 줄 수 있다. 

이 때 쓰로틀링을 적용하게 되면 불필요한 이벤트 실행 횟수를 줄일 수 있어 성능을 향상시킬 수 있다. 
쓰로틀링을 적용하면 좋은 예시로는 scroll, resize, drag, mouse 이벤트, 애니메이션 등이 있다. 

예를 들어 이 중에서 scroll 이벤트의 경우, 크롬 기준 2px  단위로 이벤트가 발생하게 된다. 
사용자가 1초에 1000px의 스크롤을 하게 되는 경우에는 약 500번의 이벤트가 발생되므로 성능에 좋지 않을 수 있다. 

이러한 경우에 time = 100 간격으로 이벤트가 실행되도록 쓰로틀링을 적용하면 실행 횟수를 10번으로 줄일 수 있다.

const DELAY = 500;
const handleScroll = () => {
  timer = null;
  console.log('스크롤!');
}
        
let timer;  
   
window.addEventListener('scroll', () => {
  if (!timer) timer = setTimeout(handleScroll, DELAY);
});

쓰로틀링도 디바운싱과 마찬가지로 SetTimeout함수와 time(기준시간)이 필요하다 .

이벤트가 발생했을 때, timer 변수의 값이 비어있다면 콜백 함수를 반환하는 SetTimeout함수를 값으로 할당한다. 
그리고 콜백 함수 내에서는 timer를 null 값으로 초기화 해준다. 

이러한 방법으로 time 이내에 최대 1번의 콜백 함수만 실행하도록 보장하게 된다.  

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
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
글 보관함