본문 바로가기

🌼 TIL

🌞 1/31 내배캠 React 66일차 [Throttling & Debouncing]

Throttling and Debouncing

: 짧은 시간 간격으로 연속해서 이벤트가 발생했을 때 과도한 이벤트 핸들러 호출을 방지하는 기법

예시 (게임에서 클릭을 계속해도 총알은 일정한 간격으로 나가는 것)

Throttling 이란?

예시 (게임에서 클릭을 계속해도 총알은 일정한 간격으로 나가는 것)

타입 : 크게 3가지 leading edge / trailing edge / leading & trailing edge

보통 무한스크롤 할때 자주 사용한다.

Leading Edge (선두 event)

: event가 발생했을 때, 첫번째 함수를발동하고 딜레이를 준다, 특정 딜레이 타임이 지나가면 다시 event를 호출하고, 다시 딜레이타임을 준다.

Trailing Edge (마지막 event)

: 특정 딜레이 타임을 주고 마지막 event에서 함수를 준다 → 그리고 다시 딜레이 타임을 주고 event함수를 준다.

leading edge와 반대라고 생각하면 됨

Leading & Trailing Edge

: leading 과 trailing 을 합쳐서 사용하는 것이다. 첫번쨰 이벤트에서 함수를 발동하고 마지막 이벤트에서도 함수를 발동한다 그 첫번째 이벤트와 마지막 이벤트 사이에 딜레이타임을 주고, 마지막 이벤트 다음 이번트가 다시 첫번째 이벤트가 된다.

let timerId = null;

//throiiling 부분
  const throttle = (delay) => {
    if (timerId) {
      return;
    }
    console.log(`API 요청 실행 ! ${delay}ms 동안 추가요청 안받음`);
    // setTimeout 이 실행되어 timerId가 실행되기 때문에 delay되고 함수가 실행된다.
    timerId = setTimeout(() => {
      console.log(`${delay}ms 지남 추가요청 받음`);
      timerId = null;
    }, delay);
  };

return (
	<button onClick={() => throttle(2000)}>트롤링</button>
)

// timeId는 기본으로 null을 줘서 true,false값으로 나오게 한다
// if timeId가 true 라면 그대로 return 하고
// 다음으로 setTimeout 을 실행하여 timeId가 실행되기 때문에 delay 된 함수가 실행된다.
// delay값 = 여기선(2000ms), 2-> 가 delay되고 다음 클릭이 실행된다.
// 첫번째 click event가 발생될 시 함수가 호출되어 2초가 딜레이되고 다음 이벤트가 발생될 때까지 기다리다가 실행된다. 

Debouncing

De+Bouncing

Bouncing?

: 회로에서 스위치가 on, off를 반복하는 현상

→ bounding을 막자는 뜻

예시 ) 키보드에 입력값 입력하자마자 모든 걸 다 서버에 받아오려하면 서버가 너무 힘들어 하기 때문에 입력값을 모두 입력할 때 까지 기다리다가 마지막에만 함수가 발동될 수 있도록 한다.

let timerId = null;

// debounce 함수 부분
  const debounce = (delay) => {
    if (timerId) {
      clearTimeout(timerId);
    }
    timerId = setTimeout(() => {
      console.log(`마지막 요청으로부터 ${delay}ms지났으므로 API요청 실행`);
      timerId = null;
    }, delay);
  };

return (
	<button onClick={() => bounce(2000)}>바운스</button>
)

// debounce는 마지막 event에 함수를 실행시킨다
// clearTimeout이 바로 실행되어서 이 전에 아무리 클릭을 해도 함수가 실행되지 않고,
// click event가 실행계속되다가 만약에 마지막으로 click을 멈추면 그로부터 2초 후 함수가 발동된다.
// 그러면 클릭을 계~~~속 하다가 멈추고 2초후에 콘솔이 찍히는 것!!!

Resize 이벤트

: 화면을 줄였다 넓힐 때는 이벤트가 일어나도 가만히 있다가 화면 사이즈가 변경 되었을 때만 함수를 호출하는 것 → Debouncing을 적용을 많이 한다.

한번 알아볼 것!

setTimeout?

: 시간을 지연시켜주는 함수

특정 코드를 사용자의 의도에 따라 시간을 지연시켜주는 함수. 즉, delay하는 함수이다.

시간을 줘서 정지시키는 역할

예)

function printAction(){
 
          setTimeout(function() { window.print();    }, 1000);
 
     }

clearTimeout?

: 정지된 시간을 푸는 역할 즉, 타이머를 취소시키는 것.

setTimeout으로 지연시킨 함수를 즉, 정지된 시간을 clearTimeout을 통해 풀 수 있다.

참고

clearTimeout이 사용되는 경우(Debouncing)

useCalback

리액트에서 Throttling/Debouncing 시 useCalback을 적용하는 이유에 대해 공부해보자

메모리 누수 (setTimeout)

필요하지 않은 메모리를 계속 점유하고 있는 현상

setTimeout은 메모리 누수를 유발하는가?

: 상황에 따라 달라질 수 있다.

보통은 메모리 누수를 유발하지 않지만 SPA에서는 클릭을 하여 다른 컴포넌트를 띄우게 되면 ( = 즉, 다른 페이지로 넘어가게 되면) 이전의 컴퍼넌트는 잠깐 삭제되게된다. (그냥 잠깐 사라지게 된다) 그런데 setTimeout이 진행되는 와중에 (server에서 데이터를 가져오고 있는 중에) SPA에서 다른 컴포넌트로 이동하게 되면, setTimeout은 계속해서 다른 컴포넌트에서 server 데이터를 찾고 있는거니까 당연히 찾고 싶은 데이터는 못가져오게 되면서 계속 멤돌게 된다. 그러면 당연히 메모리 누수가 있다.

참고 자료

setTimeout() - Web APIs | MDN

clearTimeout() - Web APIs | MDN

클로저 - JavaScript | MDN

다양한 함수 라이브러리 Lodash

Lodash Documentation