기본적으로 휠 스크롤을 빠르게 만들기

Sahel Sharify
Sahel Sharify

wheel 스크롤/확대/축소 성능을 개선하려면 개발자는 {passive: true} 옵션을 addEventListener()에 전달하여 wheelmousewheel 이벤트 리스너를 패시브로 등록하는 것이 좋습니다. 이벤트 리스너를 패시브로 등록하면 브라우저에 휠 리스너가 preventDefault()를 호출하지 않는다고 알리고 브라우저는 리스너를 차단하지 않고도 안전하게 스크롤과 확대/축소를 실행할 수 있습니다.

문제는 휠 이벤트 리스너가 개념적으로 수동적이지만 (preventDefault()를 호출하지 않음) 명시적으로 그렇게 지정되지는 않으므로 브라우저가 JS 이벤트 처리가 완료될 때까지 기다려야 스크롤/확대/축소를 시작할 수 있다는 것입니다. 기다릴 필요가 없는 경우에도 마찬가지입니다. Chrome 56에서는 touchstarttouchmove의 이 문제를 수정했으며, 이 변경사항은 나중에 Safari와 Firefox에서 모두 채택되었습니다. 당시 제작한 데모 동영상에서 볼 수 있듯이 이 동작을 그대로 두면 스크롤 응답에 눈에 띄는 지연이 발생합니다. 이제 Chrome 73에서는 wheelmousewheel 이벤트에 동일한 개입을 적용했습니다.

개입

이번 변경사항의 목표는 개발자가 코드를 변경하지 않고도 사용자가 휠이나 터치패드로 스크롤을 시작한 후 디스플레이를 업데이트하는 데 걸리는 시간을 줄이는 것입니다. 측정항목에 따르면 루트 타겟 (창, 문서 또는 본문)에 등록된 wheelmousewheel 이벤트 리스너의 75% 가 수동 옵션의 값을 지정하지 않으며 이러한 리스너의 98% 이상이 preventDefault()를 호출하지 않습니다. Chrome 73에서는 루트 타겟 (창, 문서 또는 본문)에 등록된 wheelmousewheel 리스너가 기본적으로 수동으로 변경됩니다. 즉, 다음과 같은 이벤트 리스너가

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()에 전달하여 기본 동작을 재정의하고 이벤트 리스너를 차단으로 유지합니다.