[Javascript] 디바운싱(debouncing)과 쓰로틀링(throttling)

seoyeon·2023년 4월 19일
4

Javascript 공부하기

목록 보기
12/20
post-thumbnail

작업을 하던 중 리사이즈 이벤트를 추가로 넣었는데 서버가 과부하가 걸려버렸다.

콘솔을 살펴보니 아래와 같은 메시지가 떴다

[violation] 'resize' handler 밀리초 소요됨

해당 오류는 resize 이벤트 핸들러 함수가 실행될 때, 해당 함수 내부에서 수행되는 작업이 무거워서 브라우저가 응답에 지연이 발생했음을 나타낸다.

이를 해결하는 방법으로는 디바운싱(debouncing)쓰로틀링(throttling) 등의 기술을 사용할 수 있다.

디바운싱(debouncing)쓰로틀링(throttling) 은 사실 자바스크립트의 개념이라기 보다는 프로그래밍 기법 중 하나입니다. 둘 다 디바이스의 무리를 주지 않기 위해 사용되는데 일종의 최적화 라고 볼 수 있습니다. 🫢💡

1. 디바운싱(debouncing)

연이어 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것

이벤트 핸들러가 너무 자주 호출되는 것을 방지하고자 할 때 사용됩니다.

예를들어 검색하는 API가 있다고 가정해봅시다. '안녕하세요'를 검색창에 친다고 했을 때, 일반적인 경우 각 글자를 입력할 때마다 API를 요청하게 됩니다.

이 경우 서버에 너무 많은 HTTP 요청이 들어가게 되면서 서버 자원의 부담으로 이어지기 쉽습니다. 쿼리 하나 하나가 다 돈이기 때문에 비용적인 문제와도 관련이 있죠. 😯

📝 사용방법

script

window.addEventListener('input', debounce(function(e) {
    console.log(e.target.value);
}, 200));

function debounce(func, delay) {
    let timer;
    return function() {
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(this, args);
        }, delay);
    }
}
  1. window 객체에 사용자가 입력할 때마다 발생하는 input 이벤트를 등록합니다.
  2. debounce 함수를 호출하여 input 이벤트가 발생할 때마다 실행되는 함수를 전달합니다.
  3. debounce 함수는 내부적으로 타이머를 실행하여 일정 시간(200ms)이 지난 후에 함수를 실행합니다. 타이머가 실행될 때마다 clearTimeout 함수를 사용하여 이전 타이머가 존재한다면 취소합니다.
  4. func.apply(this, args)를 호출하여 실제 실행될 함수를 실행합니다. 여기서는 e.target.value 값을 출력하는 함수가 실행됩니다.

이렇게 하면 여러 번 호출되지 않습니다!

즉 사용자가 타자를 치는동안은 함수를 호출을 무시하고 200ms동안 입력이 없으면 입력을 끝난 것으로 간주하고 함수를 실행합니다.
이를 통해 너무 빈번한 이벤트 발생으로 인한 성능 저하를 방지할 수 있죠 😎

2. 쓰로틀링(throttling)

일정 시간 동안 이벤트 핸들러를 한 번만 실행하도록 제어하는 것

쓰로틀링은 일정 시간 동안 특정 이벤트가 연속해서 발생하더라도, 일정 주기마다 최대 한 번의 이벤트만 실행되도록 하는 기술입니다. 이를 통해 연속으로 발생하는 이벤트의 처리를 제어하고, 성능 향상을 도모할 수 있습니다.

예를 들어, 스크롤 이벤트를 처리할 때 스크롤 이벤트가 지나치게 빈번하게 발생하면 성능 저하가 발생할 수 있습니다. 이때 쓰로틀링을 적용하면, 일정 주기마다 스크롤 이벤트를 처리하여 성능을 개선할 수 있습니다.

📝 사용방법

javascript

window.addEventListener('input', throttle(function(e) {
    console.log(e.target.value);
}, 200));

function throttle(func, delay) {
    let timer;
    return function() {
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(this, args);
        }, delay);
    }
}

쓰로틀링도 똑같이 적어줍니다! debounce만 바꿔주면 끝~

결과도 비슷하게 나오죠?

input 이벤트가 발생할때 마다 throttle 함수를 실행하는데 200ms이내에 새로운 input 이벤트가 발생했을 경우 그 이벤트는 무시되고, 그 사이에 발생한 이벤트들 중 첫 번째 이벤트에 대한 함수 호출 결과만 나타나는거에요.

3. 뭐가 다르지?

그림으로 나타낸것 중에 저는 이게 이해가 제일 잘 되었어요 😊
출처: https://velog.io/@kskim625/디바운싱-쓰로틀링

쓰로틀링 은 연이어 호출되는 함수들 중에서 첫 번째 함수만을 호출하여 주어진 시간동안 후속 이벤트를 무시하는 것이고, 디바운싱 은 연이어 호출되는 함수들 중에서 이전 이벤트를 무시하고 마지막 함수만을 호출하는 것입니다.

쓰로틀링은 스크롤 이벤트에 자주 쓰이고 디바운싱은 주로 ajax 검색에 자주 쓰인다고 하네요. 쓰임에 따라 적절히 사용하면 될 것 같습니다!

오늘도 지식+1 🤗


📄 참고자료

쓰로틀링과 디바운싱
자바스크립트의 디바운싱과 쓰로틀링

0개의 댓글