wheel
스크롤/확대/축소 성능을 개선하려면 개발자는 {passive: true}
옵션을 addEventListener()
에 전달하여 wheel
및 mousewheel
이벤트 리스너를 수동적으로 등록하는 것이 좋습니다. 이벤트 리스너를 수동으로 등록하면 휠 리스너가 preventDefault()
를 호출하지 않으며 브라우저가 리스너를 차단하지 않고 안전하게 스크롤 및 확대/축소를 실행할 수 있음을 브라우저에 알립니다.
문제는 대부분의 경우 휠 이벤트 리스너는 개념적으로 수동이지만 (preventDefault()
를 호출하지 않음) 명시적으로 지정되지 않아서 대기할 필요가 없더라도 스크롤/확대/축소를 시작하기 전에 브라우저가 JS 이벤트 처리가 완료될 때까지 기다려야 한다는 점입니다. Chrome 56에서는 touchstart
및 touchmove
의 이 문제가 해결되었으며 나중에 Safari와 Firefox에서 이 변경사항을 채택했습니다. 이 시점에 만든 데모 동영상에서 알 수 있듯이 이 동작을 그대로 두면 스크롤 응답이 눈에 띄게 지연됩니다. 이제 Chrome 73에서는 동일한 개입을 wheel
및 mousewheel
이벤트에 적용했습니다.
개입
이 변경사항의 목표는 개발자가 코드를 변경할 필요 없이 사용자가 휠이나 터치패드로 스크롤하기 시작한 후 디스플레이를 업데이트하는 데 걸리는 시간을 줄이는 것입니다. 측정항목에 따르면 루트 대상 (창, 문서 또는 본문)에 등록된 wheel
및 mousewheel
이벤트 리스너의 75% 가 수동 옵션의 값을 지정하지 않으며 이러한 리스너의 98% 이상이 preventDefault()
를 호출하지 않습니다. Chrome 73에서는 루트 대상 (창, 문서 또는 본문)에 등록된 wheel
및 mousewheel
리스너가 기본적으로 수동 모드로 변경됩니다. 이는 다음과 같은 이벤트 리스너를 의미합니다.
window.addEventListener("wheel", func);
다음과 동일합니다.
window.addEventListener("wheel", func, {passive: true});
리스너 내에서 preventDefault()
를 호출하면 다음과 같은 DevTools 경고와 함께 무시됩니다.
[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312
고장 및 안내
대부분의 경우 파손이 관찰되지 않습니다. 드문 경우지만(측정항목에 따라 페이지의 0.3% 미만) 기본적으로 수동적으로 처리되는 리스너 내에서 preventDefault()
호출이 무시되어 의도하지 않은 스크롤/확대/축소가 발생할 수 있습니다. 애플리케이션에서는 preventDefault()
호출이 defaultPrevented
속성을 통해 효과가 있었는지 확인하여 실제로 이 상황에 충돌이 발생할 수 있는지 확인할 수 있습니다. 영향을 받은 사례를 수정하는 방법은 비교적 간단합니다. {passive: false}
를 addEventListener()
에 전달하여 기본 동작을 재정의하고 이벤트 리스너를 차단으로 보존하면 됩니다.