728x90

쓰로틀링(throttling)과 디바운싱(debouncing). 이름은 꽤 들어봤는데, 언제, 왜 쓰는지 잘 몰라서 정리해보려고 합니다. 

 

쓰로틀링마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것입니다. 예를 들어, 스크롤을 올리거나 내릴 때, 스크롤을 움직이는 내내 함수가 호출되면 곤란하겠죠? 이럴 때, 일정 시간이 지나기 전에는 다시 호출하지 않는 쓰로틀링을 사용합니다. 

 

디바운싱연이어 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것입니다.

 

예를 들어, 검색창에 '돌고래'라는 검색어를 입력할 때 한 글자 한 글자('ㄷ', '도', '돌' ...) 칠때마다 ajax 요청이 실행됩니다. 

더보기

ajax 요청 - 쉽게 말해 서버로 (여기서는) 검색어 데이터를 보내고, 해당하는 결과물을 받아오기 위한 요청이라고 생각하면 됩니다. 

이렇게 한 글자 한 글자에 대해 모두 요청이 가면, 유료 API를 사용하게 될 경우 심각한 비용 문제를 낳을 수 있습니다. 던지는 쿼리 하나 하나가 다 돈이기 때문입니다. 

 

그러면 '돌고래' 라는 검색어를 다 입력한 후에 ajax 요청을 보내는 것이 좋겠죠

 

어떻게 구현하는 게 좋을까요? '돌고래'를 입력할 때, '돌' 치고 한참 후에 '고' 이런 식으로 입력하지 않고, 대부분의 사람들은 한 번에 '돌고래'라고 입력하지 않을까요? 그러면 이렇게 검색어의 입력이 다 끝난 후에 ajax 요청을 보내면 됩니다. 

 

검색어를 입력할 때(input 이벤트 발생)마다 타이머를 설정합니다. 이때, 예를 들어, 200ms동안 입력이 없으면, 입력이 끝난 것으로 치고, 만약, 200ms 이전에 타자 입력이 발생하면 이전 타이머는 취소하고 다시 새로운 타이머를 설정하면 됩니다. 

 

let timer; 
document.querySeletor('#input').addEventListener('input', function(e){
	if(timer){clearTimeout(timer);}
   	timer = setTimeout(function(){ 
    		console.log('200ms가 지났으니, 이제 ajax 요청을 보냅니다.', e.target.value); 
    	}, 200); 
}); 

 

이렇게 설정하면, 매번 검색어를 입력할때마다 호출되지 않고, 더 이상 입력이 없을 때, ajax 요청을 보냅니다. 이게 디바운싱입니다. 

 

쓰로틀링은 보통 성능 문제 때문에 많이 사용한다고 합니다. 스크롤을 올리거나 내릴 때를 생각해보면, scroll 이벤트가 매우 많이 발생합니다. scroll 이벤트가 발생할 때 복잡한 작업을 실행하도록 설정했다면, scroll 이벤트가 매우 빈번하게 실행되기 때문에 렉이 엄청나게 걸릴 것입니다. 이럴 때 쓰로틀링을 걸어둡니다. 몇 초에 한 번, 혹은 몇 밀리초에 한 번씩만 실행되게 제한을 걸어 두는 것입니다.  

 

위에서 디바운싱으로 구현했던 ajax 검색을 쓰로틀링으로 대체해도 됩니다. 똑같이 200ms 제한을 걸어둡니다. 타이머가 설정되어 있으면 아무 동작도 하지 않고, 타이머가 없다면 타이머를 설정합니다. 타이머는 일정 시간 후에 스스로 해제하고, ajax 요청을 날리게 하면 됩니다. 

 

let timer;
document.querySelector('#input').addEventListener('input', function(e){
	if(!timer){
    		timer = setTimeout(function(){
        		timer = null; 
            		console.log('200ms가 지나면 ajax 요청', e.target.value); 
         	}, 200);
   	}
}); 

 

이렇게 설정하면 200ms마다 요청을 보내게 됩니다. 물론, 디바운싱으로 구현하는 게 요청을 덜 보내게되겠지만, 중간 중간 검색 결과를 보여주고 싶다면 쓰로틀링도 나쁘지 않은 방법인 것 같습니다. 

 

아래 링크를 참고하여 작성했습니다.

www.zerocho.com/category/JavaScript/post/59a8e9cb15ac0000182794fa

728x90

+ Recent posts