처음에 저는 requestAnimationFrame이 리페인트 이전에 계산이 일어나는 함수로 알고 있었습니다. 그런데 이것이 이벤트 루프와 관련이 있다는 블로그 글을 읽게 되면서 의문이 생겼습니다. 정말로 requestAnimationFrame이 매크로 큐에서 관리되는 걸까요?
rAF는 Macro Queue에서 관리될까?
이 궁금증을 해결하기 위해 많은 자료를 찾아보았고, 결론적으로 requestAnimationFrame은 이벤트 루프의 매크로 큐와 직접적인 관련이 없다는 사실을 알게 되었습니다. 그 이유는 다음과 같습니다.
- 큐(Queue)는 기본적으로 FIFO(First In First Out) 형식의 자료구조입니다.
- 큐에 포함된 항목은 일반적으로 취소할 수 없습니다.
- 하지만 requestAnimationFrame은 cancelAnimationFrame을 통해 취소가 가능합니다.
이러한 특성은 requestAnimationFrame이 단순한 큐 구조로 관리되지 않음을 시사합니다.
setTimeout과의 비교
이 시점에서 setTimeout과 clearTimeout에 대해 생각해볼 수 있습니다. setTimeout 역시 취소가 가능한데, 이것도 큐와 관련이 없는 걸까요?
setTimeout의 실행 과정은 다음과 같습니다.
- 타이머 맵에 콜백 함수를 등록합니다.
- 지정된 시간이 지나면 매크로 태스크 큐에 해당 함수를 등록합니다.
- 이벤트 루프에 의해 콜 스택에 올라가 실행됩니다.
여기서 중요한 점은 clearTimeout이 큐에 들어간 함수를 취소하는 것이 아니라, 타이머 맵에 등록된 콜백 함수를 해제한다는 것입니다. 즉, setTimeout은 맵으로 관리되면서 실행 순서만 큐로 관리되는 구조입니다.
rAF의 실제 동작
requestAnimationFrame(rAF)은 분명 순서를 가지고 사용자 디스플레이 주사율에 맞춰 실행되는 비동기 함수입니다. 하지만 이를 단순히 큐로 관리된다고 말하기에는 부족한 점이 있습니다.
오히려 rAF는 큐보다 더 복잡한 자료구조를 통해 관리된다고 이해하는 것이 더 정확할 것 같습니다. 이 구조는 다음과 같은 특성을 가져야 합니다.
- 실행 순서를 유지할 수 있어야 함
- 특정 항목을 중간에 취소할 수 있어야 함
- 디스플레이 주사율과 동기화될 수 있어야 함
대략적 다이어그램을 그려보면 다음과 같습니다.
다음 codesandbox 코드를 통해서 확인할 수 있는 부분 입니다.
새로 고침을 계속해서 실행한다면, setTimeout과 requestAnimateFrame의 실행순서가 보장되지 않는 것을 확인할 수 있습니다.
결론
requestAnimationFrame이 큐에서 관리된다는 말은 정확하지 않습니다. 이는 큐의 기본적인 특성과 rAF의 동작 방식이 일치하지 않기 때문입니다. rAF는 보다 복잡하고 유연한 자료구조를 통해 관리되며, 이는 브라우저의 렌더링 엔진과 밀접하게 연관되어 있습니다.
아래 질문의 답변이 가장 정확한 답변이라 생각하여 참조하였습니다. (근거가 HTMLStandard를 기준으로 작성되었기 때문)