데브코스 교육 내용에서 자동 저장 편집기 기능을 구현하면서 디바운싱에 대해 학습했엇고 흥미가 생겨 디바운싱에 대해 더 찾아보다가 쓰로틀링도 알게 되었다.
디바운싱, 쓰로틀링은 자바스크렙트에서 과도한 이벤트 호출을 제한하는 기법이다. 주로 성능 최적화를 위해 사용된다.
쓰로틀링과 디바운싱을 사용하기 위해서는 setTimeout 비동기 메서드의 이해와 setTimeout이 반환하는 타임아웃 아이디(Timeout ID)라는 상수를 반환하는 것을 알고 있어야한다.
타임아웃 아이디는 setTimeout() 함수를 호출할 때마다 내부적으로 생성되는 타이머 객체를 가리키고 있고 이 값을 인자로 clearTimeout() 함수를 호출하면 실행될 코드를 취소 할 수 있다.
디바운싱은 연속된 이벤트에 대해 지정된 시간동안 이벤트 호출을 무시하고, 지정된 시간이 경과한 후 마지막 이벤트만을 처리하는 기법이다. 연속적인 이벤트가 발생하더라도 일정 시간 동안은 아무런 동작을 하지 않다가 시간이 지나면 마지막으로 발생한 이벤트에 대한 처리를 수행한다.
this.timer = null;
this.$editor.querySelector('[name=title]').addEventListener('keyup', (e) => {
if (timer !== null) {
clearTimeout(timer);
}
const nextState = { ...this.state, title: e.target };
this.timer = setTimeout(async () => {
setItem(postLocalSaveKey, {
...post,
tempSaveData: new Date(),
})
this.setState(nextState);
onEditing(this.state);
}, 3000);
});
먼저 keyup 이벤트가 발생하면 onEditing함수로 API를 호출하여 데이터를 수정하는 이벤트 핸들러 로직이다.
일반적으로는 입력 1개당 1개의 API를 호출하여 과도한 이벤트를 호출하게 되는데 디바운싱을 이용하여 무수한 입력 이벤트가 발생해도 마지막 입력의 이벤트만 로직이 실행되어 API를 1번 호출한다.
3초 안에 입력 이벤트가 계속해서 발생하면 if 제어문 분기에서 이전 setTitmeout의 이벤트 로직을 다 태운다.
그리고 지정한 시간 3초 이내에 새로운 입력 이벤트가 없으면 그제서야 clearTimeout이 호출되지 않아 마지막 이벤트 딱 1개만 setTimeout의 로직이 실행되어 현재 수정된 상태 값으로 데이터를 수정하게 된다.
쓰로틀링은 연속적으로 발생하는 이벤트 중 일정 시간 간격마다 하나씩만 처리하는 기법이다. 연속적인 이벤트가 발생하더라도 설정한 시간 간격마다 첫 번째 이벤트만 처리하고, 그 사이에 발생하는 이벤트는 무시합니다.
this.timer = null;
this.$editor.querySelector('[name=title]').addEventListener('keyup', (e) => {
if (this.timer) {
return;
}
const nextState = { ...this.state, title: e.target };
this.timer = setTimeout(async () => {
setItem(postLocalSaveKey, {
...post,
tempSaveData: new Date(),
});
this.setState(nextState);
onEditing(this.state);
this.timer = null;
}, 3000);
});
위 디바운스로 자동 저장 편집기 이벤트 핸들러를 쓰로틀링으로 변형해봤다.
초기 timer는 null로 timer 값이 존재하는 경우 if문 분기에서 모두 태우고 있다. 이 말은
이미 setTimeout 함수가 호출되어 지정된 시간을 기다리는 중이라면 이후 모든 이벤트를 취소하는 것이다.
setTimeout가 호출되면 timer 값이 갱신되고 이후 이벤트를 모두 취소하게 되면서 지정한 시간 3초가 지나게되면 timer 값을 다시 null로 갱신하게 된다.
이때 timer 값은 null이므로 새로운 이벤트를 받을 수 있게된다. 이러한 루프 방법이 쓰로틀링이며 요약하자면 3초마다 한 번씩 이벤트를 처리한다고 볼 수 있다.