debounce, throttle은 이벤트의 반복 실행시 콜백 함수의 불필요한 실행을 줄이는 역할을 한다. 이로 인해 클라이언트가 혜택을 볼 수도 있거나 혹은 서버 측에 불필요한 리퀘스트를 줄일 수도 있다.
예를 들어 우리가 실시간으로 ‘감사합니다’ 를 검색할때 ㄱ,ㅏ,ㅁ,ㅅ,ㅏ,ㅎ,ㅏ,ㅂ,ㄴ,ㅣ,ㄷ,ㅏ라고 칠때 연관 검색어가 같은걸 빨리 바꿔줄수있는데 너무 빨리 한다면 서버 요청이 날아가는걸 막기위해 특정시간마다 1번씩 또는 키보드 입력이 멈출때만 1번 연관검색이 뜨게 줄일수있다. 따라서 이런 연관 검색어 부분의 여러차례 빈번하게 발생하게되는 랜더링도 막아 줄수있다.
이러한 debounce, throttle을 간편하게 구현할수 있도록 만든 라이브러리가 Lodash이다. 물론 라이브러리를 사용하지 않고 직접 구현할 수도 있다.
- debounce: 동일 이벤트가 반복적으로 시행되는 경우 마지막 이벤트가 실행되고 나서 일정 시간(밀리세컨드)동안 해당 이벤트가 다시 실행되지 않으면 해당 이벤트의 콜백 함수를 실행한다.
- throttle: 동일 이벤트가 반복적으로 시행되는 경우 이벤트의 실제 반복 주기와 상관없이 임의로 설정한 일정 시간 간격(밀리세컨드)으로 콜백 함수의 실행을 보장한다.
이런식으로 onChnage 처럼 를 import 하고 변수를 각각 debounce, throttle 이라고 한다음 안에 debounce, throttle 함수를 사용하여 input 속성 onChange 값에 넣어줘서 비교해본다. Debounce 같은경우 이벤트가 계속 있다면(키보드입력값) 그때동안은 카운트하지않다가 이벤트가 끝날때(키보드를 치지않을떄)그떄부터 200milliseconds 을 카운트한후 거기에 있던 값을 console 로 찍어주었다.
Throttle 경우는 이벤트가 발생한후 이벤트가 끝나지 않더래도 정해진 시간을 카운트하여 출력해준다. 정확한 비교는 아래에 정리한다.
그런데 위에처럼 onChange안에서 state을 Set할경우 debounce가 원래대로 작동안하고 입력한대로 계속 출력해준다. 이유는 search 컴포넌트가 함수형 컴포넌트이기떄문이다. 리랜더링될때 변수들도 초기화되기때문에 설정한시간을카운트하지않고 throttle은바로 뽑아내거나, debounce는 이벤트가끝날때 똑같은값이 쏟아진다.
그래서 이럴때 useCallback 을 쓴다. 이 useCallack 은 리랜더링 되더라도 이 함수를 초기화 하지말라고 설정해준다 내가 memorizing 한 데이터는 계속쓸거다 라는것이다. 위의 사진처럼 설정해주고 실행해보면 원래 debounce 역할을 잘한다.
useCallback 인자값을 각각설명하자면 실행할 함수가 첫번째인자이고, 두번째는 useEffect처럼 []안에 들어있는 값이 변할때 초기화 해준다 라는 자리이다.
2번째 인자같은경우 우리가 원하는 debounce 와 throttle을 제대로 실행하려면 초기화시켜주면 안되므로 이땐 빈공간으로 해놓는다.