자바스크립트의 내장함수인 requestAnimationFrame()에 대하여 알아봅니다.



# 자바스크립트 requestAnimationFrame() 메소드 알아보기

자바스크립트에서 애니메이션을 구현하는 방법으로 new Date()를 사용한 타이머 함수를 만들어 사용하게 됩니다. 즉 시작 시점과 종료 시점을 직접 변수에 저장해 반복 실행하는 방법이죠.

하지만 이런 방식은 여러 문제점이 존재합니다. 먼저 불필요한 콜스택(callstack)이 지나치게 많다는 점입니다. 화면에 많은 그리기 동작을 애니메이션으로 구현해도 실제로 표시 가능한 주사율에 영향을 받으므로 지나치게 높은 부하가 발생할 수 있습니다.


! requestAnimationFrame()을 사용하여 애니메이션 향상하기
이런 경우 필요한 방법이 바로 requestAnimationFrame()입니다.

requestAnimationFrame(반복할 함수)

애니메이션 등 타이머 함수를 사용시 requestAnimationFrame()을 사용하는 이유는 무엇일까요? 몇 가지 알아보면 다음과 같습니다.

- 백그라운드 동작 및 비활성화시 중지(성능 최적화)
- 최대 1ms(1/1000s)로 제한되며 1초에 60번 동작
- 다수의 애니메이션에도 각각 타이머 값을 생성 및 참조하지 않고 내부의 동일한 타이머 참조 

실제로 애니메이션을 구현해보면 그 차이를 알 수 있습니다. 그럼 간단한 예제를 만들어보겠습니다.



# requestAnimationFrame() 예제보기
아래는 requestAnimationFrame()를 사용하여 애니메이션을 구현한 코드입니다. 코드를 실행하면 현재 시간을 1초가 지날 때까지 console로 계속해서 출력됩니다.

문제는 코드 내부를 보면 연속해서 루프가 생성되므로 Maximum callstack이 발생하는 문제입니다. 즉, 화면이 멈추는 현상이 나타나게 됩니다.

@ requestAnimationFrame(callback)
그래서 callback()을 바로 실행하지 않고 아래처럼 requestAnimationFrame(callback)로 실행했습니다.
!(function() {
  let start = new Date().getTime();
  let callback = function() {
    let ts = new Date().getTime();
    if (ts - 1000 > start) {
      // console.log('End');
    }
    else {
      console.log(ts);
      requestAnimationFrame(callback);
    }
  }
  requestAnimationFrame(callback);
})();

코드를 실행하면 어떻게 될까요? console.log()에는 무제한 호출되는 것이 아닌 단, 60번의 호출만 발생하게 됩니다. 즉 1/60으로 애니메이션이 제한됩니다. 최적화된 속도로 부드러운 애니메이션을 표현하면서 성능은 최대한 확보할 수 있게되었습니다.


! cancelAnimationFrame() 알아보기
requestAnimationFrame()를 취소하는 방법으로 cancelAnimationFrame()를 사용합니다. 마치 setTimeout()의 clearTimeout()처럼 동일하게 사용하고 동작합니다. 취소시 아래와 같이 사용합니다. 변수르 requestId를 저장하고 매개변수로 넘기면 됩니다.
myReq = requestAnimationFrame(callback);
cancelAnimationFrame(myReq);

이제 requestAnimationFrame(callback)은 동작하지 않겠죠.

여기까지 requestAnimationFrame()을 알아보았습니다.