입력 핸들러 디바운스

입력 핸들러는 프레임 완료를 차단하고 추가적이고 불필요한 레이아웃 작업을 유발할 수 있으므로 앱의 성능 문제의 잠재적 원인입니다.

입력 핸들러는 프레임 완료를 차단하고 추가적이고 불필요한 레이아웃 작업을 유발할 수 있으므로 앱의 성능 문제의 잠재적 원인입니다.

요약

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

장기 실행 입력 핸들러 피하기

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

경량 스크롤: 사용자 터치와 GPU 커밋 간 지연 시간이 컴포지터만으로 최소화됩니다.

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

과도한 스크롤: 사용자 터치 후 스크롤이 차단되고 GPU 커밋이 'onTouchMove' 핸들러에 의해 지연됩니다.

즉, 실행하는 입력 핸들러가 빠르게 실행되고 컴퍼지터가 작업을 수행할 수 있도록 해야 합니다.

입력 핸들러에서 스타일 변경 피하기

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

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

과도한 스크롤; requestAnimationFrame 후에 스타일 읽기를 예약하면 강제 동기화 레이아웃이 발생합니다.

스크롤 핸들러 디바운스

위의 두 가지 문제에 대한 해결책은 동일합니다. 항상 시각적 변경을 다음 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);

이렇게 하면 입력 핸들러를 가볍게 유지하는 추가적인 이점도 있습니다. 이제 계산 비용이 많이 드는 코드에서 스크롤 또는 터치와 같은 항목을 차단하지 않으므로 좋습니다.