웹 프로그래밍 고급 주제들

[HTML + JavaScript] Passive Event Listener

영바이트 2022. 9. 30. 08:44

 

개발을 진행하다 'Unable to preventDefault inside passive event listener invocation' 에러 로그를 마주치게 되어서 오류의 원인인 passive event listner에 대해 알아보게 되었다. 먼저 아래 블로그에 그 내용이 자세히 정리되어 있다.

 

https://velog.io/@ginameee/Passive-Event-Listener

 

Passive Event Listener

최근 업무에서 특정 React 컴포넌트의 기본 wheel event의 동작을 막아달라는 니즈가 있었다.위 내용을 처리하면서 대충 알고있던 Passive Event Listener 대해서 조금 더 자세히 들여다보게 되었다.브라우

velog.io

 

어떤 HTML 요소에 이벤트 핸들러를 등록하게 되면 이벤트가 발생하면 등록된 이벤트 핸들러를 실행하게된다. 가장 기본적인 이벤트 처리 동작이라 할 수 있다.
하지만 이벤트 핸들러 등록 시 아래와 같이 이벤트 리스너 함수의 마지막 인자로 { passive: true }와 같이 전달하면 이벤트 핸들러가 passive event로 등록된다.

 

targetElement.addEventListener('click', (event) => { ... }, { passive: true });

 

Passive event listener는 브라우저의 이벤트 처리 과정이 기본 event listener와는 다르다. 이를 비교하면 아래와 같다.

ⓐ Default event listener
Main thread: 이벤트 발생 → Renderer thread: 이벤트가 발생한 영역에 등록된 이벤트 핸들러 확인 → Main thread: 이벤트 핸들러 실행 → Renderer thread: 화면 스크롤 등 렌더링 작업 수행

ⓑ Passive event listener
Main thread: 이벤트 발생 → Renderer thread: 이벤트가 발생한 영역에 등록된 이벤트 핸들러 확인 → Main thread: 이벤트 핸들러 실행 + Renderer thread: 화면 스크롤 등 렌더링 작업 수행

 

정리하면 passive event listener에서는 등록된 이벤트 핸들러가 완료되기를 기다리지 않고 화면 스크롤 등 렌더링 작업을 함께 수행한다. 

 

위와 같은 passive event listener의 속성 때문에 passive event listener 안에서는 preventDefault( ) 함수가 동작하지 않게끔 되어 있다. preventDefault( ) 함수의 사용 목적이 이벤트 핸들러의 기본 동작을 중지하고 다른 작업들이 실행되도록 해 주는데 있는데 passive event listener에서는 이벤트 핸들러와 브라우저의 다른 함수들이 비동기적으로 동시에 실행되기 때문이다. 만약 passive event listener에서 preventDefault( ) 함수를 호출하면 'Unable to preventDefault inside passive event listener invocation' 에러 로그가 발생한다.