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

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

고장 및 안내

대부분의 경우 파손이 관찰되지 않습니다. 드문 경우지만(측정항목에 따라 페이지의 0.3% 미만) 기본적으로 수동적으로 처리되는 리스너 내에서 preventDefault() 호출이 무시되어 의도하지 않은 스크롤/확대/축소가 발생할 수 있습니다. 애플리케이션에서는 preventDefault() 호출이 defaultPrevented 속성을 통해 효과가 있었는지 확인하여 실제로 이 상황에 충돌이 발생할 수 있는지 확인할 수 있습니다. 영향을 받은 사례를 수정하는 방법은 비교적 간단합니다. {passive: false}addEventListener()에 전달하여 기본 동작을 재정의하고 이벤트 리스너를 차단으로 보존하면 됩니다.