JS ES6 문법은 아니지만, 지연 처리를 효율적으로 구현할 수 있다. 디바운싱, 쓰로틀링 모두 서버의 데이터를 요청하는 등의 작업에서 생기는 부하를 크게 줄여준다.

디바운싱(debouncing)

디바운싱의 정의는 연이어 호출되는 함수들 중에서 마지막 함수 or 맨 처음 함수만 호출하도록 하는 것이다. 간단하게 연관 검색어 창을 떠올려보자.

1
2
3
4
5
6
<input id="search" />
<script>
document.querySelector("#search").addEventListener("input", (e) => {
console.log("서버 ajax 검색 요청", e.target.value);
});
</script>

만약 이 코드대로 검색 시스템을 만들었다면, 사용자가 자바를 검색하면 ,,,자바 4개의 ajax 요청이 들어가게 된다. 쿼리 하나하나가 비용이 들기 때문에 100명의 사용자가 평균 20번의 input event가 발생한다고 치면 2000번의 비용이 발생한다는 것이다.

대부분의 사람들은 타자를 연달아서 친다. 따라서 입력이 다 끝난 후에 요청을 보내면 된다. 이 때 타자를 칠 때마다 타이머를 설정하는데, 100ms동안 입력이 없으면 입력이 끝난 것으로 치고, 100ms동안 입력이 발생하면 타이머를 새로 설정한다.

1
2
3
4
5
6
7
let timer;
document.querySelector("#search").addEventListener("input", (e) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
console.log("서버 ajax 검색 요청", e.target.value);
}, 100);
});

이제 맨 처음 들었던 예시처럼 모든 input event 경우에 대해 ajax 요청이 들어가지 않는다. 100ms동안 자바를 모두 입력했다면 자바라는 요청 한 번만 들어가게 된다. 이렇게 디바운싱은 서버 부하를 현저히 줄일 수 있다는 장점이 있다.

쓰로틀링(throttling)

쓰로틀링은 디바운싱 개념과 비슷하지만 입력하는 동안에도 바로 이전에 요청한 작업을 주기적으로 실행하는 점이 다르다. 이해가 어렵다면, 페이스북 스크롤을 생각해보자. 일명 이 무한 스크롤 기능이 디바운싱으로 구현되어 있다면 스크롤리 멈추지 않는 한 다음 타임라인은 로딩되지 않을 것이다.

위에서 예로 들었던 검색 기능을 쓰로틀링으로 다시 작성해보자.

1
2
3
4
5
6
7
8
let timer;
document.querySelector("#search").addEventListener("input", (e) => {
if (!timer) {
timer = setTimeout(() => {
timer = null;
console.log("서버 ajax 검색 요청", e.target.value);
}, 100);
});


디바운싱과 달리 쓰로틀링으로 짠 이 코드는 검색 요청을 100ms마다 보낸다. 타이머가 설정되어 있으면 아무 동작도 하지 않다가, 타이머가 없다면 타이머를 설정한다. 타이머는 일정 시간 후에 스스로를 해제하고, 검색 요청을 보낸다.

참조 ZeroCho