해당 글은 1/12에 노션으로 작성한 걸 2부로 나눈 것입니다. 이번 포스팅은 Debounce, Throttle, 이벤트 시뮬레이션을 다룬 것입니다.
여기서는 간단히 다루도록 하겠다. 아예 안 다루기에는 이벤트 최적화 방법 중 하나라 애매하기 때문이다.
다만 throttle, debounce 함수의 단점이 존재한다.
동작원리를 보면 알다시피 둘 다 setTimeout이라는 WebAPI에 의해 실행되는데 setTimeout, setInterval은 정확한 지연 시간을 보장해주지 않는다.
저번에 비동기 API Tasks들을 Task Queue에 넣어둔 후 순차적으로 처리한다는 것을 보았었는데 Queue에 저장된 비동기 태스크를 처리하는 시점은 Call Stack이 비어져 있을 경우이다.
→ 이 때 시점이 setTimeout 또는 setInterval에 할당해준 delay와 맞지 않는 경우 등록해둔 callback은 실행되지 않을 수도 있다. 즉, 정교함은 약간 떨어질 수 있다는 것이다.
debounce 내부 코드를 뜯어보면 기존과 차이점이 다음과 같다.
requestAnimationFrame은 브라우저의 화면 갱신 주기에 맞추어 함수를 호출하는 방법으로, 화면이 새로 그려질 때(Repaint)마다 함수가 실행한다.
즉, 실제 화면이 갱신되어 표시되는 주기에 따라 함수를 호출해주기 때문에 자바스크립트가 프레임 시작 시 실행되도록 보장한다.
requestAnimationFrame을 이용해 쓰로틀링 적용하고 repaint를 개선한 사례에 대한 글이다.
scroll event 최적화로 웹페이지 성능 개선하기
스크롤 이벤트 관리 시 해당 API를 사용하면 해결할 수 있다.
Intersection Observer API는 상위 요소 또는 최상위 문서의 viewport와 대상 요소 사이의 변화를 비동기적으로 관찰할 수 있는 수단을 제공한다.
Intersection Observer API는 특정 요소가 다른 요소와의 교차점에 들어가거나 나갈 때 또는 두 요소 간의 교차점이 지정된 양만큼 변화될 때 실행되는 콜백 함수를 코드에 등록할 수 있다.
즉, 기존 scroll 이벤트의 문제점을 개선하고자 개발되었다.
해당 부분의 자세한 부분은 여기서 확인할 수 있다.
실무에서 느낀 점을 곁들인 Intersection Observer API 정리
결국 Intersection Observer를 이용한다는 것은 WebAPI에 이벤트를 위임하는 것이고, 따라서 자연스럽게 메인 스레드의 자유도도 보장한다고 볼 수 있다.
JS로 언제든 원하는 이벤트를 발생시킬 수 있다. 이 기능은 웹 애플리케이션을 테스트할 때 유용하다.
document의 createEvent 메서드로 event 객체를 생성하고, 이벤트에 관한 정보를 초기화한 후, dispatchEvent 메서드로 이벤트를 발생시킨다.
// 예시
// 이벤트 객체 생성
var event = document.createEvent("MouseEvent");
// 이벤트 초기화 (세부 정보 설정)
event.initMouseEvent(
"mouseover", // 이벤트 타입
true, // 버블링 여부
true, // 취소 가능 여부
window, // 이벤트가 발생한 윈도우
0, // 클릭 횟수
0, 0, // 화면 좌표
0, 0, // 클라이언트 좌표
false // 컨트롤 키 누름 여부
);
// 이벤트 발생시키기
document.getElementById("myDiv").dispatchEvent(event);
MouseEvent() 생성자를 이용하여 MouseEvent 객체를 초기화 & 생성한 후, dispatchEvent 메서드로 이벤트를 발생시킨다. MouseEvent 이외에도 KeyboardEvent, FocusEvent 등 Event Interface를 상속받는 다양한 생성자가 있다.
Event Interface?
DOM에서 발생하는 이벤트를 나타낸다.
다양한 이벤트 종류는 아래 사이트에서 참고 가능하다.
Event Interface
// MouseEvent 생성자를 직접 사용
const event = new MouseEvent('mouseover', {
bubbles: true,
cancelable: true,
view: window,
// 다른 옵션들도 한번에 설정 가능
});
// 이벤트 발생시키기
document.getElementById("myDiv").dispatchEvent(event);
다음은 활용 예시 코드이다. 이런식으로 이벤트 시뮬레이션을 사용하면 자동화된 테스트를 작성할 수 있고, 사용자 상호작용이 필요한 복잡한 기능도 쉽게 테스트할 수 있다.
function testButtonClick() {
// 버튼 클릭 이벤트 시뮬레이션
const clickEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true
});
const button = document.getElementById('submitButton');
button.dispatchEvent(clickEvent);
// 이벤트 발생 후의 결과 확인하기
assert(document.getElementById('result').textContent === '성공');
}
Debounce 와 throttle 은 뭐고 각각 언제 사용할까?