스크롤 이벤트 성능 이슈 (passive 옵션)
- 일반적으로 이벤트들은 observable이 아니고, 콜백으로만 처리된다고 믿는다.
- 그래서 side-effect가 없다고 여길 수 있는데… 몇몇 이벤트들은 observing 할 수 있도록 구현되어 있다.
touchstart
,touchmove
,wheel 이벤트
핸들러들은 이벤트 발생 시preventDefault()
를 호출하는지 확인한다. (중간에 멈춰야 하는 지 확인하기 위해)- 따라서 단순히 이벤트 리스너만 등록하더라도.. 성능 상으로는 큰 delay가 생길 수도 있다.
- 10%의 이벤트들은 100ms delay 발생, 최악의 경우(약 1%) 500ms 까지 딜레이 발생.
해결방법
element.addEventListener('touchstart', null, {passive: true});
{passive:true}
옵션을 줌으로서preventDefault
를 호출하지 않겠다고 알려준다.- 스크롤 이벤트를 막지 않겠다고 브라우저에게 알려주기 때문에, lookup 연산을 절약할 수 있다.
- 다만, (당연하게도)
preventDefault
를 사용할 수 없다. 사용 시 에러가 발생한다.
주의사항
- Chrome 54+ 부터
{passive:true}
가 default가 되기 때문에,preventDefault
작업이 필요하다면 설정해줘야 한다. - 패시브 옵션이 없는 구버전 브라우저를 지원해야 하는 경우 polyfill이나 passive 옵션을 적용하는지 검사를 따로 해줘야 한다.
// passive 옵션 지원 확인
let supportsPassive = false;
try {
const options = {
get passive() {
isPassiveSupport = true;
}
};
window.addEventListener("test", options, options);
window.removeEventListener("test", options, options);
} catch (err) {
isPassiveSupport = false;
}
element.addEventListener('touchstart', callback, supportsPassive ? { passive:true } : false);
- +) react17 부터
{passive: true}
가 디폴트이기 때문에preventDefault
가 필요할 시 옵션에 추가 해줘야 한다.