Browser Event는 짧은 시간안에 많이 발생될 수 있습니다.
브라우저에서 저희는 Drag and Drop, Draggable, Resize, Infinite Scroll과 같이 다양한 기능을 개발하기 위해 Event를 감지하는 Handler를 등록합니다.
document.addEventListener('scroll', function Handler () {
// 로직
})
그렇다면 Handler 또한 짧은 시간안에 많이 호출될 수 있습니다.
Handler는 서버와의 API 통신, 위치 계산 등 비교적 시간이 오래걸리는 작업을 포함할 수 있습니다.
이러한 로직이 짧은 시간 동안 많이 실행된다면 사용자는 불편함 UI/UX를 경험하게 될 것입니다.
결국, 성능상 이슈가 발생합니다.
최적화 방법
Browser Event의 호출 횟수를 저희가 변경할 수는 없으므로 Handler의 실행 횟수를 컨트롤 해야 합니다.
연속적으로 Handler가 실행되려고 할 때 모든 Handler를 실행시킬 수는 없으므로 언제 Handler를 실행 시킬 것인가를 결정해야 합니다.
이러한 필요에 의해 만들어진 개념이 Debounce와 Throttle입니다.
Debonuce
연속적인 호출을 하나의 호출로 그룹화 하여 일정 시간이 지난 후에 Handler를 호출하는 방법입니다.
Throttle
연속적인 호출을 하나의 호출로 그룹화 하지만 일정 시간마다 Handler의 호출을 보장합니다.
단순히 이러한 동작만으로는 모든 기능을 잘 구현하기란 힘들 수도 있습니다.
한 예로, debounce는 일정 시간 이후에 Handler를 발생시키므로 즉각적으로 Handler를 발생 시켜 UI에 반영하기 힘듭니다.
그래서 Lodash의 Debounce와 Throttle은 다양한 옵션을 제공합니다.
Debounce
Lodash의 Debounce는 다음과 같이 다양한 옵션을 제공합니다.
Default Options는 { leading: false, trailing: true } 입니다.
따라서 일정 시간이 지난 후에 Handler를 호출시킵니다.
- 단, 일정 시간 내에 Handler 호출을 시도하면 일정 시간 이후 Handler를 호출시키도록 지연시킵니다.
- 여기서 일정 시간이란 wait arguments에 해당합니다.
const wait = 300
box.addEventListener('mousemove', _.debounce(function () {
// 로직
}, wait))
만약 즉각적인 Handler 호출을 원한다면 leading을 true로 주면 됩니다.
const wait = 300
box.addEventListener('mousemove', _.debounce(function () {
// 로직
}, wait, { leading: true, trailing: false })
leading debounce test
https://codepen.io/dcorb/pen/GZWqNV
참고 자료