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
손상 및 안내
대부분의 경우 중단이 발생하지 않습니다. 드물지만(Google 측정항목에 따르면 페이지의 0.3% 미만) 기본적으로 수동으로 취급되는 리스너 내에서 preventDefault()
호출이 무시되어 의도치 않은 스크롤/확대가 발생할 수 있습니다. 애플리케이션은 preventDefault()
호출이 defaultPrevented
속성을 통해 영향을 미쳤는지 확인하여 실제로 이 문제가 발생할 수 있는지 확인할 수 있습니다. 영향을 받는 사례의 수정사항은 비교적 간단합니다. {passive: false}
를 addEventListener()
에 전달하여 기본 동작을 재정의하고 이벤트 리스너를 차단으로 유지합니다.