최대 1 분 소요

  • 일반적으로 이벤트들은 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가 필요할 시 옵션에 추가 해줘야 한다.

refs

카테고리:

업데이트: