회사에서 사용하는 자동완성 라이브러리는 대용량 데이터가 지원되지 않아서
lodash debounce를 이용하여 구현해보려고 한다.
구현하기 전에 디바운스와 쓰로틀링 개념에 대해 정리해보았다.
대부분의 경우 자동 완성, 연관 검색어 기능은 서버에서 호출해야 한다. 이러한 기능은 "검색" 버튼을 클릭하는 것이 아니라 모든 키 입력에서 발생하므로 많은 이벤트가 생성된다. 과도한 이벤트의 발생이 성능 저하를 초래하지 않도록 호출 횟수를 줄이기 위해 사용한다.
debounce는 사용자가 입력을 멈출 때까지 기다리므로 throttle보다 리소스 보호에 좋다. API 호출 시 항상 추가 지연된다는 단점이 있지만 리소스를 적극적으로 보호해야 하는 경우에는 디바운스가 적합하다.
디바운스가 항상 적합한 건 아니다. 예를 들어 사용자가 무언가를 입력하고 백그라운드에서 자동 저장 할 경우 이벤트의 흐름이 잠시 멈출 때까지 기다리는 디바운스의 특성은 위험하다. 사용자가 무언가를 입력하고 저장되기 전에 페이지를 떠날 경우 여전히 리소스는 보호하지만 상태를 저장하기 위해 모든 경우를 사용해야 한다.
throttle 서버를 보호하고 싶지만 사용자의 작업을 손실하고 싶지 않을 경우 사용한다. 자동 저장 시 debounce는 거의 호출되지 않으며 "체크포인트"를 제공하지 않기 때문에 스로틀이 좀 더 적합하다.
타이밍 기능의 가장 일반적인 예 중 하나는 스크롤 이벤트 수를 제한하는 것이다. 타이밍 기능이 없을 때 스크롤은 엄청난 양의 이벤트를 생성하므로 상호작용을 제한해야 한다. 무한 스크롤 구현이나 스크롤 위치를 계산하기 위해 스로틀 또는 디바운스를 사용하는 경우가 있지만 Intersection Observer 를 사용해야 한다.
스크롤의 진행 상황을 보여주는 기능이 있을 때 디바운스와 스로틀은 지연이 발생하며 이에 적합한 API는 requestAnimationFrame 이다.
스크롤이나 마우스 이동을 기반으로 애니메이션하는 경우 사용한다.
위의 예에서는 trailing edge를 사용했다. 에지 설정은 함수가 이벤트 스트림의 시작 또는 끝에서 실행되어야 하는지 여부를 알려준다.

스로틀의 경우 leading-edge를 선택할 때 케이스가 쉽다. 예를 들어 이벤트 스트림이 발생한 직후에 함수가 실행되고 1초 마다 실행되기를 원한다.
반면에 디바운스는 특성을 변경한다. 무언가를 한 번 실행하고 이벤트가 없는 시간(예: 1초)이 될 때까지 다른 모든 이벤트를 무시한다. 그 이후에 이벤트가 발생하면 처음에 한 번만 실행하는 것으로 돌아간다.
디바운스 및 스로틀은 lodash 에서 가져와서 구현할 수 있다. lodash는 maxWait 처럼 추가 기능이 있다. 일정 시간 동안 발생하지 않은 경우 함수를 호출할 수 있는 강력한 기능이다.
Throttle vs Debounce on real examples - 예제 👍
Intersection Observer API
window.requestAnimationFrame()