requestAnimationFrame
rAF (requestAnimationFrame)
Web API 중 하나로 브라우저 렌더링 엔진과 함께 웹 어플리케이션의 애니메이션을 부드럽게 만드는데 사용된다.
브라우저에게 수행하기를 원하는 애니메이션을 알리고, 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출하게 한다.
이 메소드는 리페인트 이전에 실행할 콜백을 인자로 받는다.
다음 리페인트에서 그 다음 프레임을 애니메이트하려면 콜백 루틴이 반드시 스스로
requestAnimationFrame()
을 호출해야 한다.
const animate = () => {
// rAF가 호출하는 콜백함수에는 반드시 rAF 호출구문을 재귀적으로 작성해야 한다.
window.requestAnimationFrame(animate);
//...
}
Event Loop

Render
60hz 기준 60fps(16.7ms)마다 브라우저를 업데이트
브라우저에 DOM 요소를 변형한것들이 표기 되기 위해서는 렌더트리를 업데이트, (Layout, Paint, Composite)단계를 거친다.
requestAnimationFrame
브라우저가 업데이트 되기전에 RequestAnimationFrame에 등록한 콜백이 실행된다. 즉, RequestAnimationFrame은 60fps를 보장한다.
rAF -> layout -> paint -> composit 단계순으로 처리된다.
Frame
화면에 표시된 하나의 정지된 이미지를 나타낸다.
애니메이션은 이 프레임들이 연속적으로 빠르게 나열되어 움직임을 나타낸것
사용자가 애니메이션을 어색 하지 않게 느끼려면 최소 1초에 60프레임(60fps)을 화면에 표시해야 한다.
모니터 주사율(Hz)
에 따라 rAF 콜백 실행 횟수가 달라지므로, 동일한 애니메이션을 제공하기 위해서는 따로 처리가 필요하다.

Hz에 상관 없이 동일한 애니메이션을 제공하는 방법
rAF 콜백 실행횟수에 상관 없이 1초에 코드가 몇번 실행될지(fps) 정해서 모든 모니터에서 동일한 시간에 동일한 움직임을 나타낼 수 있다.
1. Date.now() 함수 활용하기
60hz 기준 rAF 콜백은 16.7ms마다 실행된다.
now → rAF 콜백이 실행될때 현재 타임스탬프를 저장한 변수 ex:) 1000ms -> 1016ms -> 1032 ms
then → 애니메이션이 호출 로직이 실행된 타임스탬프를 저장한 변수
delta → 현재의 타임스탬프와 이전 애니메이션이 호출된 타임스탬프의 시간 간격을 저장하는 변수
즉,
interval
시간 간격 마다 애니메이션 동작 로직을 실행시킨다.
let interval = 1000 / 60; // 60fps
let now, delta;
let then = Data.now();
const animate = () => {
window.requestAnimationFrame(animate);
now = Data.now();
delta = now - then;
if (delta < interval) return;
/*...애니메이션 호출 로직 */
then = now - (delta % interval);
}
Last updated