-
디바운스와 쓰로틀을 사용한 최적화오늘 공부 2024. 11. 8. 22:29
자바스크립트 애프리케이션에서는 사용자가 웹페이지와 상호작용하는 동안 발생하는 다양한 이벤트들을 다루게 됩니다.
특히, scroll, resize, input, mousemove와 같은 이벤트들은 매우 짧은 시간 간격으로 연속해서 발생하는데,
이런 식으로 이벤트 핸들러가 과도하게 호출되면 성능 저하나 불필요한 서버 요청이 발생할 수 있습니다.
이런 문제를 해결하기 위해 디바운스(Debounce)와 쓰로틀(Throttle)이라는 기법을 사용해 볼 수 있습니다.
이 두 기법은 연속해서 발생하는 이벤트를 효율적으로 제어하여 성능을 최적화하는 데 도움을 줍니다.
이번 글에서 디바운스와 쓰로틀에의 활용 방법에 대해 간단하게 한번 알아보겠습니다.
| 디바운스
디바운스는 연속된 이벤트 호출을 그룹화하여 마지막에 한 번만 실행되도록 하는 방식입니다.
즉, 이벤트가 발생한 후 일정 시간이 지날 때까지 추가적인 이벤트가 발생하지 않으면 그때 한 번만 이벤트 핸들러를 호출합니다.
디바운스의 동작
디바운스는 다음과 같은 과정으로 동작합니다.
- 이벤트가 발생하면 이전에 설정된 타이머를 취소합니다.
- 새로운 타이머를 설정하여 일정 시간(delay) 후에 콜백 함수를 실행하도록 합니다.
- 만약 delay 시간 내에 다시 이벤트가 발생하면 1번 과정으로 돌아가 타이머를 취소하고 다시 설정합니다.
- 이벤트가 더 이상 발생하지 않고 delay 시간이 지나면 콜백 함수가 실행됩니다.
사용
디바운스는 보통 input 이벤트에서 자주 사용됩니다.
검색 기능을 구현할 때 자동완성을 위해 사용자가 입력할 때마다 API 요청을 보내면 서버에 부하가 걸리고,
사용자에게 불필요한 대기 시간이 발생할 수 있습니다.
이때 디바운스를 사용하여 사용자가 입력을 멈춘 후에 한 번만 API 요청을 보내도록 할 수 있습니다.
자바스크립트에서 debounce 함수는 간단하게 다음과 같이 구현할 수 있습니다.
const debounce = (cb, delay) => { let timer; // timer를 가지고 있는 클로저를 반환합니다. return e => { // delay가 경과하기 이전에 이벤트가 발생하면 이전 타이머를 취소하고 새로운 타이머를 재설정합니다. // 따라서 delay보다 짧은 간격으로 이벤트가 발생하면 콜백 함수는 호출되지 않습니다. if(timer) clearTimeout(timer); timer = setTimeout(cb, delay, e); } }
다음으로 아래와 같은 input이 있다고 하면
<input type="text" id="search" placeholder="검색어를 입력하세요">
다음과 같이 이벤트 핸들러를 적용할 수 있습니다.
const searchInput = document.getElementById("search"); const handleInput = debounce((e) => { const query = e.target.value; console.log(`검색어: ${query}`); }, 200); searchInput.addEventListener("input", handleInput);
이런 디바운스는 다음과 같은 상황에서 주로 활용됩니다.
- 검색어 자동완성 - 사용자가 입력을 멈춘 후에 검색을 수행
- 윈도우 리사이즈 이벤트 - 창 크기 변경이 끝난 후에 레이아웃 재계산
- 폼 검증 - 사용자가 입력을 완료한 후에 검증 로직 실행
- 버튼 클릭 방지 - 짧은 시간 내에 중복 클릭을 방지하여 중복 요청을 막음
| 쓰로틀
쓰로틀은 연속된 이벤트 호출을 일정한 간격마다 실행되도록 하는 방식입니다.
즉, 이벤트가 아무리 많이 발생해도 정해진 시간 간격마다 최대 한 번씩만 이벤트 핸들러가 호출됩니다.
쓰로틀의 동작
쓰로틀은 다음과 같은 과정으로 동작합니다.
- 이벤트가 발생하면 현재 시간이 이전에 실행된 시간과의 차이가 delay 이상인지 확인합니다.
- delay 이상이면 이벤트 핸들러를 실행하고, 마지막 실행 시간을 현재 시간으로 업데이트합니다.
- delay 미만이면 이벤트를 무시합니다.
사용
쓰로틀은 scroll 이벤트에서 자주 사용됩니다.
scroll 이벤트는 사용자가 스크롤할 때마다 매우 빈번하게 발생합니다.
이때 이벤트가 과도하게 호출되면 성능 문제가 발생할 수 있기 때문에
쓰로틀을 사용하여 일정 시간마다 한 번씩만 핸들러가 실행되도록 제어할 수 있습니다.
자바스크립트에서 throttle 함수는 간단하게 다음과 같이 구현할 수 있습니다.
const throttle = (cb, delay) => { let timer; return e => { // delay가 경과하기 이전에 이벤트가 발생하면 아무것도 하지 않습니다. // delay가 경과했을 때 이벤트가 발생하면 새로운 타이머를 재설정합니다. // 따라서 delay 간격으로 콜백 함수가 호출됩니다. if(timer) return; timer = setTimeout(() => { cb(e); timer = null; }, delay, e) } }
다음으로 아래와 같이 이벤트 핸들러를 적용할 수 있습니다.
const handleScroll = throttle(() => { console.log(`스크롤 위치: ${window.scrollY}`); }, 200); window.addEventListener("scroll", handleScroll);
이런 쓰로틀은 보통 무한 스크롤을 구현하는 데 사용될 수 있습니다.
| 디바운스와 쓰로틀의 차이
디바운스 쓰로틀 실행 시점 이벤트가 끝난 후 일정 시간 후에 실행 이벤트가 시작되면 일정한 간격마다 실행 사용 목적 이벤트가 끝난 후 한 번만 실행하고 싶을 때 이벤트를 일정 간격으로 실행하고 싶을 때 | 끝
디바운스와 쓰로틀은 자바스크립트에서 성능 최적화를 위해 한번쯤 반드시 공부해봐야 할 기법이라 생각합니다.
두 방법 모두 이벤트 핸들러의 호출 빈도를 제어하여 불필요한 연산을 줄이고,
사용자 경험을 향상 시키는데 큰 도움을 줄 수 있습니다.
마지막으로 위 예시는 이해를 위해 간략하게 작성된 코드이고,
실제 프로젝트에 사용할 때는 Lodash와 같은 검증된 라이브러리를 사용하는 것이 권장됩니다.
'오늘 공부' 카테고리의 다른 글
Ajax (를 알아야 하는 이유) (0) 2024.11.07