본문 바로가기

Client/Front-end

<Front-end> 쓰로틀링과 디바운싱

 

1. 소개

 - 최근에 수많은 이벤트를 발생시킬 수 밖에 없는 부분을 개발하면서 고민에 빠졌었다. 이 정도로 많은 요청이 있을때마다 이벤트를 발생시키는 것이 옳은건지, 이것을 최적화 할 수는 없는지 고민을 했다.

 

 - 예를 들면 사용자가 스크롤을 내릴 때마다 특정 함수를 발생시킨다고 가정하자. 스크롤 좌표가 바뀔때마다 함수가 실행될텐데 정말 이것이 올바른 방법일까?

 

 - 이러한 의문에 쓰로틀링과 디바운스에 대해 공부해보라는 조언을 받았고, 이렇게 정리해보려 한다.

 

 - 참고로 제목에서는 프론트엔드의 기술이라고 썼지만, 이는 순전히 필자가 웹 프론트엔드 개발자이기 때문이다. 그렇기 때문에 아래에서도 웹을 예시로 들 예정이다. 디바운싱과 쓰로틀링은 프로그래밍 기법 중 하나임을 명심하길 바란다.

 

2. 쓰로틀링

* 의미

 - 쓰로틀링(throttling), 또는 쓰로틀(throttle)은 전자-컴퓨터 공학에서 하드웨어에 과부하를 줄 경우 성능을 낮추고 억제하는 것을 의미한다. 

 

 - 쓰로틀은 조절판이라는 의미를 갖고 있으며, 쓰로틀링은 (목을)조르다 의 의미를 갖고있다. 즉 과도한 요청이 있을 때, 마치 수도꼭지를 조으듯이 잠시 억제 또는 무시하는 것이다.

 

 - 위 둘을 정리하여 프론트엔드 관점에서 보자면, 연속적으로 발생하는 이벤트에 대해, 일정 시간을 묶어 그 시간이 지나기 전까지는 무시하는 방식을 의미한다.

 

* 예시

 - 쓰로틀링이 사용될 수 있는 예시를 보자.

 

<section>
  <div class="top">TOP</div>
  <div class="middle">MIDDLE</div>
  <div class="bottom">BOTTOM</div>
</section>

 

- 간단하게 스크롤 이벤트를 구성하기 위해 html 파일을 위와같이 작성하였다.

 

let number = 0;
const onScroll = () => {
  number++;
  console.log(number);
};
window.addEventListener("scroll", onScroll);

 

 - 자바스크립트파일은 위와 같이 작성하였으며, window에 스크롤 이벤트를 걸어서 스크롤마다 숫자를 1씩 증가시키며 출력하도록 하였다.

 

 - 이를 브라우저에서 실행해보자.

 

 

 - 위의 영상을 보면 알 수 있듯이 스크롤 이벤트가 무수히 많이 발생하여 출력이 과도하게 됨을 알 수 있다.

 

 - 만일 스크롤을 이용한 더 무거운 함수를 만들어 실행한다면 의도치않게 함수가 많이 실행될 것이다.

 

 - 이럴 때 필요한 것이 쓰로틀링이다. 한 번 실행되고 나서 일정시간동안 이벤트를 무시하게된다면 원하는 만큼 실행할 수 있게 된다.

 

* 적용

 - 자바스크립트에서 쓰로틀링은 아래와 같은 코드로 적용해 볼 수 있다.

let number = 0;
let throttler;
const onScroll = () => {
  if (throttler) return;
  throttler = setTimeout(() => {
    number++;
    console.log(number);
    throttler = null;
  }, 100);
};
window.addEventListener("scroll", onScroll);

 

 - setTimeout을 이용하여 타이머 객체를 통째로 임의의 변수 throttler에 넣었다. 

 

 - 위 코드의 경우 0.1초동안은 이벤트를 잠궈 한번만 실행되도록 하였고, 0.1초 후에 함수를 실행한 후 비로소 잠굼을 해제하고 있다.

 

 - 따라서 0.1초간은 임의의 변수 throttler에 타이머객체가 있기 때문에 스크롤 이벤트가 발생하더라도 무시된다.

 

 - 쓰로틀링을 적용하여 함수발생을 위처럼 조절할 수 있게되었다.

 

3. 디바운스

* 의미

 - 디바운싱(debouncing) 또는 디바운스(debounce)는 전자 컴퓨터 공학의 bouncing과 관련된 용어이다. bouncing은 스위치들이 접점에서 떨어지거나 붙는 시점에 물리적으로 미세하게 여러번 on/off가 되는 현상이다.

 

 - 즉 바운싱은 의도는 한번의 on/off이나 원하지않는 수많은 on/off가 발생하는 것이다. 이를 막으려는 방법이 debouncing이다.

 

 - 디바운싱은 여러 이벤트가 발생할 때, 이들을 하나의 그룹으로 묶어서 처리한다. 

 

 - 이 때, 주로 그룹에서 마지막에 처리된 함수를 처리한다.

 

* 예시

 - 이번엔 스크롤 이벤트가 아닌 form의 제출이벤트를 예시로 보자.

 

<form>
  <input id="input" type="text" />
  <button type="submit">submit</button>
</form>

 

 - input에는 텍스트를 입력할 수 있으며, 엔터 혹은 버튼을 클릭하면 submit이벤트가 발생한다.

 

const form = document.querySelector("form");

const onSubmit = (e) => {
  e.preventDefault();
  const input = document.querySelector("#input");
  console.log("제출완료 :", input.value);
};

form.addEventListener("submit", onSubmit);

 

 - submit이벤트가 발생할 시에는 input의 value값을 출력하도록 하였다.

 

 

 - 한 글자씩 입력할때마다 엔터를 눌렀으며, 마지막에는 제출 버튼을 연속적으로 클릭하는 영상이다.

 

 - 당연히 엔터 혹은 버튼 클릭마다 submit이벤트가 발생하고, 함수가 실행된다.

 

 - 하지만 위 상황이 api요청이라면 어떨까. 유저가 검색을 실수해서 얼른 고쳐서 재요청할 수도있고, 장난삼아 제출버튼을 여러번 누를 수도 있다. 그렇게되면 서버에 수많은 요청이 가서 과부하가 걸릴 수도 있고, 만일 외부 api를 이용중이어서 한 번 요청에 일정금액이 청구된다면 생각만 해도 끔찍하다.

 

 - 이럴 때 필요한 방식이 디바운싱이다. 모든 요청을 하나로 보고 한 번만 요청하는 것이다. 위의 사례에서도 적용할 수 있도록 가장 마지막 요청에만 실행하는 방식을 적용해보자.

 

* 적용

 - 코드는 다음과 같다.

 

const form = document.querySelector("form");
let debouncer;
const onSubmit = (e) => {
  e.preventDefault();
  const input = document.querySelector("#input");
  if (debouncer) {
    clearTimeout(debouncer);
  }
  debouncer = setTimeout(() => {
    console.log("제출완료 :", input.value);
  }, 1000);
};

form.addEventListener("submit", onSubmit);

 

 - 쓰로틀링과 달리 타이머 객체 바깥에서 타이머 객체가 있으면 클리어해주는 것을 볼 수 있다.

 

 - 위를 통해 시간(예시에서는 1초)안에 다시 요청이 발생하면 앞의 요청은 제거하고, 최신 요청을 1초후에 실행하도록 할 수 있다.

 

 

 - 위에서 봤던 영상과 동일하게 한 글자 입력마다 엔터를 눌렀다. 사에서 잠시 멈추었기때문에 함수가 실행되었다.

 

 - submit버튼을 아무리 여러번 누르더라도 가장 마지막 요청만 처리되도록 했음을 알 수 있다.

 


참고

 

 

[JS] 디바운싱(Debouncing)과 쓰로틀링(Throttling)

디바운싱(Debouncing)과 쓰로틀링(Throttling) 디바운싱(Debouncing)과 쓰로틀링(Throttling) 은 사실, 자바스크립트의 개념이라기 보다는 프로그래밍 기법중 하나입니다. 둘 다 디바이스(일반적으로 CPU)의

programming119.tistory.com

 

 

(JavaScript) 쓰로틀링과 디바운싱

안녕하세요. 이번 시간에는 쓰로틀링(throttling)과 디바운싱(debouncing)에 대해 알아보겠습니다. 원래 예정에 없던 강좌이지만 요청을 받았기 때문에 써봅니다. 프로그래밍 기법 중 하나입니다(아니

www.zerocho.com