"Life is Full of Possibilities" - Soul, 2020

IT (프론트엔드)

스크롤 동작 최적화를 위한 옵션, "Passive event listener"

m2ndy 2023. 9. 23. 22:26

Passive Event Listener?

Chrome 51 부터 등장한 스크롤 동작 최적화를 위한 옵션.
터치 이벤트나 마우스 휠 이벤트 동작 시 사용됩니다.

 

먼저 어떤 느낌인지 비교를 하자면, 다음 영상을 참고해 주세요.



터치 또는 휠 이벤트 시 퍼포먼스를 대폭 향상시킬 수 있는 옵션이며, 모바일 환경에서 경험할 수 있습니다.

따라서 스크롤의 성능을 최적화하고 싶을 때 사용하는데, preventDefault의 동작이 실행되는 것을 막을 수 있습니다.





addEventListener로 등록된 이벤트는 Compositor thread에서 처리됩니다.
원래대로라면, 이벤트를 Main thread에 넘긴 뒤 자신은 Render tree를 다시 넘겨받을 때까지 대기상태가 됩니다.


그런데 passive 옵션이 활성화(true)되어 있다면, Compositor thread는 Main thread를 기다리지 않고 자신의 작업을 즉시 수행하게 됩니다.
이벤트를 수신하자마자 핸들러를 실행하고, 화면에 바로 반영하여 렌더링 퍼포먼스가 향상될 수 있습니다.




passive : true




passive 옵션이 true인 경우 Main thread를 거치지 않고 작업을 바로 실행해주기 때문에, Main thread에서 처리되는 preventDefault가 실행되지 않습니다.
| preventDefault : 어떤 이벤트를 명시적으로 처리하지 않은 경우, 해당 이벤트에 대한 사용자 에이전트의 기본 동작을 실행하지 않도록 지정합니다. / 참고 : MDN : Event.preventDefault()



즉, preventDefault는 cancelable (취소 가능한 이벤트)의 기본 동작을 취소하는 이벤트입니다.
| cancelable : 체크박스와 같이 취소 가능한 이벤트


예시로, 체크박스에 preventDefault 조건을 걸어주게 되면 체크박스에 체크가 되지 않습니다.



터치, 스크롤, 휠과 같은 이벤트는 취소해야 할 일이 거의 없으며, 특성상 짧은 시간에 빠르고 많이 발생합니다.
만약 passive 옵션이 false 상태인 경우 이벤트가 다 끝날때까지 기다렸다가 화면에 반영을 하게 되어 버벅이는 등의 현상이 발생할 수 있습니다.
passive 옵션을 활성화 하게 되면, 이벤트가 수신되는 즉시 화면에 반영해도 됨을 알려주는 것이고 퍼포먼스 향상을 기대할 수 있습니다.




"Unable to preventDefault inside passive event listener invocation."


터치, 스크롤 등의 이벤트를 발생시키는 코드를 작성하다 보면, 위와 같은 에러가 발생할 수 있습니다. 해당 이벤트 내에 preventDefault가 실행되고 있는데, `passive: true` 속성으로 인해 preventDefault가 실행되지 않고 있다는 의미입니다.

  • Chrome 54부터 기본값은 passive: true


따라서 event.addEventListener('event', func, {passive: false})와 같이 passvie 옵션을 비활성화 상태로 선언하여 해결할 수 있습니다.
하지만 렌더링 퍼포먼스를 향상시키는 passive 옵션을 비활성화했기 때문에, 좋은 퍼포먼스를 기대할 수는 없다는 단점이 있습니다.




참고

MDN https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener
Github WICG/EventListenerOptions https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
Passive Event Listener https://velog.io/@ginameee/Passive-Event-Listener
Passive Event Listeners https://velog.io/@sejinkim/Passive-Event-Listeners