requestAnimationFrame()

들어가기 전

setInterval()를 사용하다보면, 디바이스 하드웨어에 따라 성능이 차이난다. \
오래된 모바일 디바이스에서 실행하면, 배터리가 빠르게 소진되고 버벅이는 현상을 목격 할 수 있다.\
이러한 단점을 보안하기위해서 나온 것이 requestAnimationFrame() 이다

개념

브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출하게 합니다. \
즉, 브라우저가 에니메이션을 수행할 준비가 되어있을때 수행합니다. \
이 메소드는 리페인트 이전에 실행할 콜백을 인자로 받습니다. \
디스플레이 주사율과 일치하게 callback을 호출하지만, 보통 60 frame/s을 지원한다.

브라우저가 다음 화면을 그리기 전

'브라우저가 다음 화면을 그리기 전' 이라는말.. 더 자세히 알고 싶었다. \
구글링 해보니, 픽셀 파이프라인을 설명해준 페이지가 있었고, 여기서 자세히 알 수 있었다. \
'브라우저가 다음 화면을 그리기 전'이라는 말은 아래의 파이프라인이 실행되기 전으로 이해할 수 있었다. \
setInterval로 충분히 할 수 있는거 같은데 왜 굳이 이런걸 알아야 할 수 있는데, 해당 API가 어마어마한 장점이 있다.
rendering
이미지 출처

장점

디바이스 배터리 절약 효과

  • background tab일 경우 에니메이션 멈춤
  • 감추어진 iframe에서 수행 시 에니메이션 멈춤

API Spec

callback

  • 1개 변수를 받는다.
  • 보통 1초에 60번 호출되지만, 웹브러우저의 display refresh rate (디스플레이 주사율)에 따른다.
  • 그 값은 해당 문서의 처음 로드 되었던 시간으로 부터 현 시간이다. (unit: millisecond)

return 값

  • requestAnimationFrame(callback)을 호출하면 long int 값을 받는다.
  • 해당 int값은 requestAnimationFrame 호출했던 pk이다
  • pk를 이용해서 animation을 종료시킬 수 있다. 예) cancelAnimationFrame(pk)

setInterval과 차이점

  • setInterval은 스스로 반복해서 호출하지만, 해당 API는 재귀적으로 호출해야한다. \
  • 프레임을 고려안하고 지정된 시간내에서만 실행되므로, 프레임이 누락되고, 사용자에게는 버벅거리는 화면을 보여줌

setTimeout
이미지 출처

Example

let id
function sample() {
    console.log('sample')
    id = requestAnimationFrame(sample)
}

requestAnimationFrame(sample)
//cancelAnimationFrame(id)

참고

requestAnimationFrame() official