입력 핸들러 디바운스

입력 핸들러는 프레임 완성을 차단할 수 있기 때문에 앱에서 성능 문제를 일으키고 불필요한 추가 레이아웃 작업을 유발할 수 있습니다.

입력 핸들러는 프레임 완성을 차단할 수 있으므로 앱에서 성능 문제를 일으키고 불필요한 추가 레이아웃 작업을 유발할 수 있습니다.

요약

  • 오래 실행되는 입력 핸들러를 피하세요. 스크롤을 차단할 수 있습니다.
  • 입력 핸들러에서 스타일을 변경하지 마세요.
  • 핸들러를 디바운스하세요. 이벤트 값을 저장하고 다음 requestAnimationFrame 콜백에서 스타일 변경을 처리하세요.

오래 실행되는 입력 핸들러 피하기

가장 빠른 가능한 경우, 사용자가 페이지와 상호작용할 때 페이지의 컴포지터 스레드는 사용자의 터치 입력을 받아서 콘텐츠를 간단히 이동할 수 있습니다. JavaScript, 레이아웃, 스타일 또는 페인트가 수행되는 기본 스레드에서는 작업이 필요하지 않습니다.

스크롤이 경량이며 컴포지터 전용입니다.

그러나 touchstart, touchmove 또는 touchend와 같은 입력 핸들러를 연결하는 경우 컴포지터 스레드는 이 핸들러가 실행을 완료할 때까지 기다려야 합니다. preventDefault()를 호출하고 터치 스크롤이 발생하지 않도록 할 수 있기 때문입니다. preventDefault()를 호출하지 않더라도 컴포지터는 대기해야 하므로 사용자의 스크롤이 차단되어 끊김 현상 및 프레임 누락이 발생할 수 있습니다.

과도한 스크롤: 컴포지터가 JavaScript에서 차단되었습니다.

간단히 말하면, 실행하는 모든 입력 핸들러가 빠르게 실행되고 컴포지터가 작업을 수행할 수 있도록 해야 합니다.

입력 핸들러에서 스타일 변경 방지

스크롤 및 터치와 같은 입력 핸들러는 requestAnimationFrame 콜백 직전에 실행되도록 예약됩니다.

이러한 핸들러 중 하나에서 시각적 변경을 수행하면 requestAnimationFrame 시작 시 스타일 변경사항이 대기 중입니다. 그런 다음 requestAnimationFrame 콜백 시작 시 시각적 속성을 읽으면 '크고 복잡한 레이아웃 및 레이아웃 스래싱 피하기'에서 제안한 대로 강제 동기식 레이아웃이 트리거됩니다.

과도한 스크롤: 컴포지터가 JavaScript에서 차단되었습니다.

스크롤 핸들러 디바운스

위의 두 문제에 대한 해결책은 동일합니다. 시각적 변경사항을 항상 다음 requestAnimationFrame 콜백으로 디바운스해야 합니다.

function onScroll (evt) {

    // Store the scroll value for laterz.
    lastScrollY = window.scrollY;

    // Prevent multiple rAF callbacks.
    if (scheduledAnimationFrame)
    return;

    scheduledAnimationFrame = true;
    requestAnimationFrame(readAndUpdatePage);
}

window.addEventListener('scroll', onScroll);

이렇게 하면 입력 핸들러를 가볍게 유지할 수 있는 추가적인 이점이 있습니다. 계산 비용이 많이 드는 코드의 스크롤이나 터치 등을 차단하지 않기 때문에 정말 좋습니다!