본문으로 건너뛰기

requestAnimationFrame

자바스크립트를 사용하여 사용자에게 부드러운 애니메이션을 구현하려면 16.6ms 밀리초마다 코드를 호출하는 식으로 구현해야한다. setTimeout은 주어진 시간에 동작을 할 뿐 프레임을 신경쓰지 않고 동작한다.

프레임 드랍을 방지하려면 rAF(requestAnimationFrame)을 사용할 수 있다.

rAF함수는 시스템이 프레임을 그릴 준비가 되면 애니메이션 프레임을 호출하여 애니메이션 웹페이지를 보다 원활하고 효율적으로 생성할 수 있도록 해준다. 실제 화면이 갱신되어 표시되는 주기에 따라 함수를 호출해주기 때문에 자바스크립트가 프레임 시작 시 실행되도록 보장해주어 위와 같은 밀림 현상을 방지한다.

setInterval같은 경우 브라우저의 다른 탭 화면을 보거나 브라우저가 최소화되어 있을 때 계속 타이머가 돌아 콜백을 호출하기 때문에 시스템 리소스 낭비를 초래하고 불필요한 전력을 소모하게 만든다.

반면 requestAnimationFrame는 페이지가 비활성화 된 상태이면 페이지 화면 그리기 작업도 브라우저에 의해 일시 중지됨으로 CPU 리소스나 배터리 수명을 낭비하지 않게 된다.

디스플레이 주사율에 맞게 호출 횟수 이 특징은 최적화된 웹 애니메이션을 구현하는데 있어 setInterval 과 requestAnimationFrame 의 결정적인 차이점이라고 말할 수 있다. 지금까지 1초에 60번 호출한다고 써왔지만, 정확히 말하자면 자신의 모니터가 60hz 주사율 모니터일 경우이다. 즉, 웹브라우저는 디스플레이의 주사율을 따르며 만일 144hz 주사율 고사양 모니터일 경우 rAF 역시 1초에 144번 호출되게 된다. 정리하자면 setInterval 에서는 콜백 함수 호출 간격을 시간을 지정해주고 호출 횟수를 설정하지만, rAF에서는 모니터의 주사율을 그대로 따르게 되어 최적화 되어 있다는 것이다. 그리고 이러한 특성 때문에 rAF는 스크롤 이벤트 최적화 기법으로도 쓰이기도 한다.

모든 DOM 조작이나 애니메이션은 requestAnimationFrame을 기반으로 해야한다. 이 콜백 내에서 DOM 작업을 수행하면 더 효율적이 된다. 이 API는 메인 스레드를 차단하지 않으며 다음 repaint가 이벤트 루프에서 스케줄링되기 전에 실행된다.