Developer/Javascript

Throttle와 Debounce 개념 알고 상황에 맞게 쓰기

jaddong 2023. 3. 2. 22:23
320x100

Throttle 과 Debounce 의 필요성이 나온 이유

1. 검색창에서 "떡볶이"를 검색할 때

타이핑을 할 때마다 텍스트 필드 하단에 입력한 검색어와 맞을 만한 추천 검색어를 하단에 보여주게된다. 이런 경우 매번 입력할 때마다 api를 호출해본다고 생각해보자. 사용자 경험으로는 추천 검색어를 바로 볼 수 있기 때문에 좋을 수는 있으나, 사용자의 의도와 무관한 요청이 계속 된다면 이것은 성능적으로 매우 좋지 않은 결과가 있을 수 있다. 또한 api의 호출이 잦아 로딩이 길어진다면 사용자의 경험에도 안 좋은 영향을 줄 수 있다.

 

2. Infinite scrolling page(무한 스크롤 페이지)

사용자가 스크롤을 할 때마다 새로운 컨텐츠가 하단에 무한으로 보여지는 되는 UX는 요즘 어디서나 쉽게 찾아볼 수 있다.(트위터, 인스타그램 등)사용자가 스크롤을할 때 footer와의 거리를 계산해서 컨텐츠를 불러오는 온다고 생각해보자. 그렇다면 onScroll 이벤트가 계속 일어날때마다 footer와의 거리를 계산해서 api를 호출할 것인가? 이것 또한 api호출이 무분별하게 많아질 수 있으므로 성능상이 이슈가 있을 수 있다.

 

3. 티켓팅 결제나 댓글을 등록할 때 등록 버튼을 여러번 연속으로 클릭한다면? 

요즘은 거의 없겠지만 댓글을 등록을 할 때 등록을 여러번 클릭해 동일한 댓글이 두 번 달린 경험이 있을 것이다. 등록버튼을 클릭하고 바로 disabled하거나 막지 않으면 동일한 폼을 여러번 submit하게 되어 의도와 다르게 여러번 게시될 수 있다.

 

 

그래서 이런 문제점을 보완하고자 Throttle 과 Debounce개념이 나왔다. 이벤트가 발생할 때마다 function을 실행하게되면 성능상이 이슈가 있으므로, 이벤트가 발생되는 동안 function이 계속 실행되지 않도록 일정한 시간을 주는 것을 말한다.

 

 

 

Throttle 과 Debounce 이란

스크롤 예제 하나로 아주 쉽게 이해할 수 있다.

1. Nothing : 스크롤할 때마다 function이 실행

2. Throttle : 스크롤을 할 때 일정한 시간 간격을 두고 정기적으로 function을 실행

3. Debounce : 아무리 많은 스크롤해도 모두 무시하고 특정 시간 사이에 어떤 스크롤도 발생하지 않았을 때 딱 한번만 마지막 function을 발생시키는 기법

 

 

 

Throttle 과 Debounce 원리

loadsh에 있는 throttle과 debounce를 코드를 까보면 이런 식으로 구현되어 있다.

 

debounce의 경우 이벤트가 실행되었을 때 일정 시간을 기다렸다가 이벤트를 수행하도록 만들고, 일정 시간 내에 같은 이벤트가 또 들어오면 이전 요청을 취소하는 방식으로 구현한다.

function debounce(callback, delay) {
  let timer;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => {
      callback.apply(this, arguments);
    }, delay);
  };
}

 

throttle은 타이머가 없을 경우 타이머를 설정하고, 타이머가 있을 경우 아무런 동작도 하지 않도록 하여 일정 시간 이후에 이벤트가 1번 실행되도록 구현한다.

function throttle(callback, delay) {
  let timer;
  return function () {
    if (!timer) {
      timer = setTimeout(() => {
        callback.apply(this, arguments);
      }, delay);
    }
  };
}

 

Throttle 과 Debounce 를 언제 사용해야하나

throttle이나 debounce는 사실 정답이 없고 상황에 맞춰서 사용해야한다.

 

검색창에 타이핑을 할 때 100ms 마다 자동완성검색창이 나왔으면 한다면 throttle을 사용해야하겠고, 어느정도 타이핑을 다 입력하고 이벤트가 멈췄을 때 자동완성이 보이는 걸 원한다면 debounce를 사용하면 되겠다.

하지만 보편적으로 쓰이고 있는 경우는 아래와 같다.

 

Throttle

- 무한 스크롤 기능 : SNS에서 자주 쓰이는 무한 스크롤 기능에서는 debounce보다 throttle이 적합하다. 유저가 스크롤링을 멈출 때까지 기다렸다가 새로운 글을 불러오는 것보다는 유저의 스크롤이 어느 정도 내려왔을 때 미리 글을 불러오는 것이 좀 더 좋은 경험을 제공할 수 있기 때문이다.

- 브라우저 resize : resize 이벤트는 빈번하게 발생될 수 있기 때문에, 이벤트 핸들러는 DOM 수정과 같은 계산이 많이 필요한 연산을 실행하지 않아야 한다. 대신에 이벤트를 스로틀(throttle) 하는것이 좋다. -> MDN 사이트

 

Debounce

- toggle버튼 : 알림설정 toggle 버튼은 수시로 쉽게 수정할 수 있다. 이 경우 toggle 이벤트 리스너에 어느 정도 debounce를 줘서 마지막으로 일어난 toggle의 요청만 처리하는 것이 유저에게 좋은 경험일 것이다.

- 자동완성 검색어 : 한 글자씩 타이핑할 때마다 api를 호출하여 자동완성 검색을 하단에 바뀌도록 보여주는 것보다는 어느정도 단어가 완성된 후 자동완성을 제공해주는 것이 성능상에도 유저의 경험에도 더 적절할 것이다.

 

 

 

여담

전에 회사에서 사내에서 사용하는 백오피스의 버튼에 debounce나 throttle같은 기능을 해놓지 않아 버그처럼 보였던 경험이 있다. 그리고 scroll에 따라 element의 스타일이 변경되는 작업도 해보았어서 이번 공부를 통해 이벤트 핸들링에 대해 더 예민하게 봐야할 필요가 있다는 생각이 들었다. debounce나 throttle는 이벤트나 함수들의 실행되는 빈도를 줄여서 성능상의 유리함 가져기도 하지만 유저의 경험에도 직접적으로 영향을 줄 수 있기 때문이다.

 

 

참고

- https://webclub.tistory.com/607

- https://css-tricks.com/debouncing-throttling-explained-examples/

- https://pks2974.medium.com/throttle-%EC%99%80-debounce-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0-2335a9c426ff

- https://medium.com/@kwoncharles/debounce%EC%99%80-throttle%EC%9D%98-%EC%B0%A8%EC%9D%B4-34845fbfa1ff

 

Throttle 와 Debounce 개념 정리하기

Throttle 와 Debounce 라는 개념 을 알게 되어 이를 정리해보고자 한다.

pks2974.medium.com

 

Debouncing and Throttling Explained Through Examples | CSS-Tricks

The following is a guest post by David Corbacho, a front end engineer in London. We've broached this topic before, but this time, David is going to drive the

css-tricks.com

 

디바운스(Debounce)와 스로틀(Throttle ) 그리고 차이점

Throttle, Debounce & Difference 스로틀(Throttle)과 디바운스(Debounce)란 무엇일까? 이 두 가지 방법 모두 DOM 이벤트를 기반으로 실행하는 자바스크립트를 성능상의 이유로 JS의 양적인 측면, 즉 이벤트(event)

webclub.tistory.com

 

반응형