requestAnimationFrame 메소드

주기적으로 실행되는 애니메이션을 window.requestAnimationFrame()으로 최적화 해보자

requestAnimationFrame(callback)

브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트 하는 함수를 호출하게 한다. 이 메소드는 리페인트 이전에 실행할 함수를 인자로 받는다.

  • 다음 리페인트에서 그 다음 프레임을 애니메이트 하려면 콜백 루틴이 반드시 스스로 requestAnimationFrame()을 호출해야 한다.

대부분의 브라우저에서 W3C 권장사항에 따라 디스플레이 주사율만큼 호출되게 된다.

callback

파라미터인 callback은 다음 리페인트를 위한 애니메이션을 업데이트 할 때 호출할 함수이다. 콜백함수에는 requestAnimationFrame()이 콜백함수 실행을 시작할 때의 시점을 나타내는 DOMHighResTimeStamp() 단일 인자를 전달한다.

반환 값

requestAnimationFrame()을 취소할 수 있는 고유 id인 long 정수값이 반환된다.
window.cancelAnimationFrame()함수로 전달하여 취소할 수 있다.

차이점

setInterval과는 다음과 같은 차이점이 있다.

주사율만큼의 interval

setInterval을 사용하여 구현할 경우 interval을 손수 설정해주어야 한다.
requestAnimationFrame은 주사율만큼의 Interval을 가지게 된다.(설정해줄 필요가 없다.)

동시 실행

여러개의 setInterval을 사용할 경우 콜백이 겹쳐져서 버벅임이 발생할 수 있다. requestAnimationFrame을 사용할 경우 계속 실행하기 위해선 내부 callback에서 반드시 재호출해야 하므로 여러개의 애니메이션을 써도 버벅이지 않는다.

비동기

js-que

위의 동시실행과 같은 이야기지만 setTimeout, setInterval은 마이크로 태스크큐에서 작동한다. 하지만 requestAnimationFrame은 Animation Frame에서 동작한다. 때문에 setInterval과 달리 callback이 유실될 가능성이 없다.

예시

1
2
3
4
5
6
7
8
9
10
11
12
let start = null;
let hi = 0;
function callback(timestamp) {
if (!start) start = timestamp;
console.log("cnt", hi++);

if (timestamp - start <= 1000) {
window.requestAnimationFrame(callback);
}
}
window.requestAnimationFrame(callback);
// 61번 출력되었다.

Ref

window.requestAnimationFrame()

댓글