rAF란?

2026. 2. 3. 10:06TIL

참고: https://insight74278.tistory.com/1 (개발로그 | rAF로 오디오 에디터 줌 기능 버벅거림 잡기

rAF = requestAnimationFrame

requestAnimationFrame(RAF)은 다음 화면을 그리기 바로 전에 콜백(애니메이션 로직)을 실행하도록 브라우저에 요청하는 자바스크립트 내장 API다.


1. requestAnimationFrame이 하는 일

브라우저가 다음 화면을 그리기 직전에 지정한 콜백을 실행해 줍니다.

const rafId = requestAnimationFrame(() => {
    // 다음 프레임(약 16ms 후)에 실행됨
    addTrimRegion(pendingStart, pendingEnd);
});

 

2. 특징

항목 설명

실행 시점 다음 리페인트 직전
대략 주기 약 16ms (60fps 기준)
반환값 숫자 ID (취소 시 사용)
취소 cancelAnimationFrame(rafId)

 

rAFId란?

 

rafId는 requestAnimationFrame이 반환하는 숫자 ID를 저장하는 변수입니다.


1. requestAnimationFrame 반환값

const rafId = requestAnimationFrame(() => {
    // 다음 프레임에 실행될 코드
});
// rafId → 예: 1234 (브라우저가 부여한 숫자)

requestAnimationFrame은 예약 ID를 숫자로 반환합니다.


2. rafId를 쓰는 이유: 취소

// 예약
rafId = requestAnimationFrame(() => { ... });

// 나중에 취소할 때
if (rafId !== null) {
    cancelAnimationFrame(rafId);  // 이 ID로 취소
    rafId = null;
}

cancelAnimationFrame(rafId)로 아직 실행되지 않은 예약을 취소할 수 있습니다.

 

rAF 스로틀링

RAF 스로틀링 방식

이 코드에서는 **“한 번에 하나의 RAF만 예약”**하는 방식으로 스로틀링합니다.


1. 동작 방식

pointermove 1회 → pending 업데이트 → RAF 예약 (rafId 저장)
pointermove 2회 → pending 업데이트 → rafId 있음 → 새 RAF 예약 안 함
pointermove 3회 → pending 업데이트 → rafId 있음 → 새 RAF 예약 안 함
...
다음 프레임 → RAF 콜백 실행 → addTrimRegion 1회 호출 → rafId = null

핵심: 이미 RAF가 예약되어 있으면(rafId !== null) 새로 예약하지 않고, pending 값만 갱신합니다.


2. 코드 흐름

// onMove: pointermove마다 실행
if (rafId.current === null) {           // ① RAF가 아직 예약 안 됐을 때만
    rafId.current = requestAnimationFrame(() => {  // ② 다음 프레임에 실행 예약
        addTrimRegion(ps, pe);          // ③ 프레임당 1회만 실행
        rafId.current = null;           // ④ 다음 move에서 다시 예약 가능
    });
}
// rafId가 이미 있으면 → pending만 업데이트, RAF는 예약 안 함


3. 스로틀링이 되는 이유

상황 동작

첫 번째 pointermove rafId === null → RAF 예약
같은 프레임의 이후 pointermove rafId !== null → RAF 예약 안 함, pending만 갱신
다음 프레임 RAF 콜백 실행 → addTrimRegion 1회 호출 → rafId = null
그 다음 pointermove 다시 rafId === null → RAF 예약

그래서 프레임당 최대 1번만 addTrimRegion이 호출됩니다.


4. pending의 역할

여러 번의 pointermove가 한 프레임 안에 들어와도:

  • RAF 콜백은 한 번만 실행되고
  • 그때 pendingStart, pendingEnd는 가장 마지막 값을 사용합니다.

즉, 마지막 위치만 반영하고, 호출 횟수는 프레임당 1회로 제한하는 구조입니다.


5. 정리

요소 역할

rafId RAF가 이미 예약됐는지 여부
rafId === null RAF 예약 가능 → 새로 예약
rafId !== null RAF 이미 예약됨 → pending만 갱신
pendingStart, pendingEnd RAF 실행 시점의 최신 값 저장

 

참조:

https://developer.mozilla.org/ko/docs/Glossary/Throttle

https://stackoverflow.com/questions/26120838/shall-the-requestanimationframe-calls-always-be-throttled-down-to-60-fps

https://developer.mozilla.org/ko/docs/Glossary/Throttle

https://web.dev/articles/speed-rendering?hl=ko

https://inpa.tistory.com/entry/🌐-requestAnimationFrame-가이드

https://developer.mozilla.org/ko/docs/Web/API/Window/requestAnimationFrame

https://rhei.me/blog/cse/requestanimationframe-guide