티스토리 뷰

320x100

이 글은 주니어 개발자가 쓴 글로 오류가 있을 수 있습니다.
문제가 있거나 수정이 필요한 부분은 댓글로 알려주시면 감사하겠습니다.

 

프론트엔드 개발자를 위한 자바스크립트 프로그래밍(일명 노란책)을 공부하고 정리한 내용입니다.


Event 메모리와 성능 최적화

자바스크립트에서는 페이지에 존재하는 이벤트 핸들러의 개수가 페이지 성능에 직접적으로 영향을 미칩니다.

 

원인

- 각 함수가 메모리를 점유하는 객체이다. 메모리를 많이 사용할수록 성능은 떨어진다.

- 이벤트 핸들러를 많이 할당하려면 DOM 접근도 많아진다. 이는 전체 페이지의 응답성을 떨어트린다.

 

개선 방법

1. 이벤트 위임 - 이벤트 핸들러 개수 줄이기

이벤트 버블링의 장점을 활용하여 공통 부모 요소에 이벤트 핸들러를 하나만 할당해서 해당 타입의 이벤트를 모두 처리하는 테크닉입니다. 비슷한 방식으로 여러 요소를 다뤄야 할 때 사용됩니다. click, mousedown, mouseup, keydown, keyup, keypress 등의 이벤트에 적용하기 좋습니다. [활용 예시 참고]

 

2. 더 이상 필요하지 않은 이벤트 핸들러(= 잔류 핸들러) 제거하기

문서에서 요소를 제거하거나 페이지를 떠나는 경우, 요소는 제거되지만 이벤트 핸들러는 남아 메모리를 점유합니다. 요소를 제거할 것이라면 잔류 핸들러를 직접 제거하는 것이 좋고, 페이지를 떠나기 전에는 onunload 이벤트 핸들러를 이용하여 잔류 핸들러를 모두 제거하는 편이 좋습니다.

단, onunload 이벤트 핸들러를 사용하면 페이지가 bfcache에 저장되지 않기 때문에 bfcache를 사용하는 것과 잔류 핸들러를 제거하는 것 중에 뭐가 더 성능에 좋을지 선택해야 합니다.

 

참고) bfcache란?
back/forward cache의 약자로 이전/다음으로 이동할 때, 페이지 전체(힙 메모리 포함)를 캐싱하여 페이지를 로드하는 시간과 데이터를 절약하는 기법입니다.
크롬 웹 페이지의 경우 평균적으로 10번에 1번, 모바일의 경우 5번에 1번은 페이지 접속 후 바로 뒤로가기/앞으로 가기가 수행되는데, 이때마다 페이지 전체를 다시 로드하고 리소스를 불러오는 것이 사용자 관점에서 시간도 오래 걸리고, 네트워크 관점에서도 낭비가 심해서 bfcache가 생겨났다고 합니다.
이는 브라우저에서 자동으로 캐싱하는 것으로 별도의 설정을 필요로 하는 것은 아니나 unload 이벤트처럼 사용시 bfcache 대상에서 제외되는 경우가 있습니다.

이벤트 시뮬레이션

자바스크립트로 언제든 원하는 이벤트를 발생시킬 수 있습니다. 이 기능은 웹 애플리케이션을 테스트할 때 유용합니다.

 

createEvent 방식

document의 createEvent 메서드로 event 객체를 생성하고, 이벤트에 관한 정보를 초기화한 후, dispatchEvent 메서드로 이벤트를 발생시킵니다.

  • createEvent(type) - 매개변수로 넘겨진 타입의 event 객체 생성 [매개변수 참고]
  • init__Event(초기화 값) - 타입별 적합한 init 메서드로 event 객체를 초기화 (ex. initMouseEvent, initKeyboardEvent, initCustomEvent etc.)
  • EventTarget.dispatchEvent(event) - target에 넘겨진 event를 발생 시킴
// 이벤트 객체 생성
var event = document.createEvent("MouseEvent");
// 이벤트 정보 초기화
event.initMouseEvent("mouseover", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
// 이벤트 발생
document.getElementById("myDiv").dispatchEvent(event);

 

DOM 4 레벨 방식

MouseEvent() 생성자를 이용하여 MouseEvent 객체를 초기화 & 생성한 후, dispatchEvent 메서드로 이벤트를 발생시킵니다. MouseEvent 이외에도 KeyboardEvent, FocusEvent 등 Event Interface를 상속받는 다양한 생성자가 있습니다. [Event Interface 목록 참고]

// 이벤트 객체 생성 및 초기화
const event = new MouseEvent("click", {
  bubbles: true,
  cancelable: true,
  screenX: 0,
  screenY: 0,
});
// 이벤트 발생
document.getElementById("myDiv").dispatchEvent(event);

참고자료

 

320x100
댓글