프론트엔드 개발을 진행하다 보면 변경되는 특정 값에 따른 이벤트 처리를 하는 경우가 자주 발생한다. (ex. 검색 기능 구현 시 추천 검색어 표시, 스크롤 값에 따른 헤더 상단 fixed 처리 등)
이 경우 상태 값을 처리하는 이벤트가 변경되는 값에 의해 계속 실행되는데 이렇게되면 불필요한 이벤트가 실행되어 성능에 좋지 않은 이슈가 발생한다. 이를 Debouncing 과 Throttling 을 통해 최적화시켜줄 수 있다.
React 를 사용한 예제 코드를 통해 직접 실행해보면서 정리하였다.
Debouncing
값의 변경이 완료되고 일정 시간 뒤에 이벤트가 실행된다.
위의 예제는 input 을 통해서 검색값을 입력한 뒤 검색 쿼리값을 통해 API 를 호출시켜 검색 결과 값을 가져오는 상황을 가정하였다. 간단하게 상단의 코드만 보면 일반적으로 input 값을 state 에 적용시키는 코드임을 알 수 있다.
이런 식으로 해도 동작은 정상적으로 실행되지만 input 의 value 가 변경될 때마다 쿼리값도 계속 변경되기 때문에 useEffect 안의 API 를 불필요하게 호출하는 경우가 발생하게 된다.
이런 경우 디바운싱을 통해 input value 가 변경이 완료된 뒤 일정 시간이 지나면 API 를 호출할 수 있게 변경할 수 있다.
inputValue 가 변경되면
setTimeout
을 통해 일정 시간 뒤에 쿼리값을 변경시키도록 적용하였다.Throttling
값이 변경되는 중에 일정 시간마다 이벤트가 실행된다.
높이값이 5000px 인 div.scroll-inner-box 와 150px 인 div.scroll-box 항목이 있는 상태에서 스크롤을 하는 경우 scrollEvent 함수가 실행되는 상황을 가정하였다.
timer, delay 변수를 값이 변경되어도 리렌더링이 되지 않도록
useRef
로 적용시킨 뒤, timer 변수를 토글 방식으로 활용하여 일정 시간마다 callback 함수를 실행시키는 throttleFunc
함수를 생성하였다.Lodash 라이브러리
여러 가지 유용한 함수를 제공하는 lodash 라이브러리에서 디바운싱과 쓰로틀링을 제공해주고 있어 직접 만들지 않고 사용할 수 있다.
마무리
해당 글에 있는 예제 코드들은 코드 파악을 쉽게 하기 위해서 컴포넌트 안에 디바운싱과 쓰로틀링의 함수들을 추가했지만 디바운싱과 쓰로틀링은 여러 곳에서 사용이 가능해야 활용성이 좋기 때문에
lodash
라이브러리를 사용하지 않고 직접 만들어서 사용하려는 경우에는 custom hook 으로 생성하여 사용하는 것이 더 효율적이라고 생각한다. codesandbox 에 custom hook 을 적용한 예제가 있으니 참고하면 좋을 것 같다.출처