자바스크립트 requestAnimationFrame

requestAnimationFrame() 메소드는 자바스크립트에서 최적화된 성능으로 애니메이션을 구현하게해주는 중요한 메소드입니다.

이 메소드는 브라우저의 렌더링 주기(fps)에 맞춰 애니메이션을 부드럽게 실행하도록 도와줍니다.

특히 CPU와 GPU 자원을 효율적으로 사용할 수 있도록 해줍니다.

requestAnimationFrame 기본 개념

메소드의 주요 기능은 화면을 새로 고칠 때마다 애니메이션을 한 프레임씩 실행해줍니다.

화면을 갱신하는 주기는 보통 60Hz, 즉 1초에 60번(16.7ms 간격)으로 설정되어 있습니다.

이 메서드는 애니메이션을 실행할 적절한 시간에 콜백을 실행하여 프레임을 처리합니다.

이로 인해 과도한 CPU/GPU 사용을 방지하고 성능을 최적화할 수 있습니다.

문법 구문:

requestAnimationFrame(callback);

  • callback: 애니메이션 프레임을 갱신할 때 호출되는 함수입니다. 이 함수는 브라우저의 렌더링 주기마다 호출되며, timestamp라는 파라미터를 전달합니다.

예제:

function animate(timestamp) {
  console.log(timestamp); // 타임스탬프가 콘솔에 출력됩니다.
  requestAnimationFrame(animate); // 애니메이션을 계속해서 실행
}

// 애니메이션 시작
requestAnimationFrame(animate);
requestAnimationFrame 예제

먼저 animate() 함수에서는 전달받은 timestamp를 console.log() 메소드를 통해 콘솔에 출력하고 다음 애니메이션 요청으로 자기 자신을 넘깁니다.

위의 코드를 개발자 도구에서 실행하면 이미지와 같은 결과를 확인할 수 있습니다.

requestAnimationFrame 특징

  • 성능 최적화: 이 메소드는 브라우저가 화면을 갱신할 때 맞춰 콜백을 실행하기 때문에 CPU나 GPU를 불필요하게 과다하게 사용하는 일이 줄어듭니다.
  • 브라우저 최적화: 브라우저는 이를 사용한 애니메이션을 최적화하여 화면을 부드럽게 갱신합니다.
  • 일시 중지 및 복귀: 탭이 백그라운드로 이동하거나 사용자가 브라우저를 최소화하면 애니메이션이 자동으로 일시 중지됩니다. 브라우저가 다시 활성화되면 애니메이션이 자동으로 복귀합니다.

requestAnimationFrame 애니메이션 예제

예제 1: 간단한 박스 애니메이션

첫 번째 예제에서는 메소드를 사용하여 HTML 요소를 좌우로 움직이는 애니메이션을 구현해 보겠습니다.

<html>

<head>
  <style>
    #box {
      width: 100px;
      height: 100px;
      background-color: blue;
      position: absolute;
      left: 0;
    }
  </style>
</head>

<body>
  <div id="box"></div>

  <script>
    const box = document.getElementById('box');
    let position = 0;

    function animate() {
      position += 2;

      if (position > window.innerWidth) {
        position = 0;
      }

      box.style.left = position + 'px';

      requestAnimationFrame(animate);
    }

    requestAnimationFrame(animate);
  </script>
</body>

</html>
박스 애니메이션

위의 코드에서는 requestAnimationFrame() 메소드를 사용하여 box라는 HTML 요소를 좌우로 이동시키는 애니메이션을 구현했습니다.

position 값은 매 프레임마다 2px씩 증가하며, 화면의 오른쪽 끝을 넘으면 초기화되어 다시 왼쪽에서 시작됩니다.

실행하면 파란색 박스가 왼쪽에서 오른쪽으로 이동하는 것을 확인할 수 있습니다.

예제 2: 부드러운 스케일링 애니메이션

이번에는 box의 크기를 부드럽게 변경하는 애니메이션을 구현해 보겠습니다.

<html>

<head>
  <style>
    #box {
      width: 100px;
      height: 100px;
      background-color: blue;
      position: absolute;
      left: 100px;
      top: 50px;
    }
  </style>
</head>

<body>
  <div id="box"></div>

  <script>
    const box = document.getElementById('box');
    let scale = 1;
    let growing = true;

    function animate() {
      if (growing) {
        scale += 0.01;

        if (scale >= 2) {
          growing = false;
        }
      } else {
        scale -= 0.01;

        if (scale <= 1) {
          growing = true;
        }
      }

      box.style.transform = `scale(${scale})`;

      requestAnimationFrame(animate);
    }

    requestAnimationFrame(animate);
  </script>
</body>

</html>
박스 크기 변경

여기서는 scale 변수를 사용해 box의 크기를 부드럽게 확장하고 축소하는 애니메이션을 구현했습니다.

scale 값이 1에서 2 사이를 오가면서 크기를 키우고 줄이는 방식입니다.

requestAnimationFrame, setInterval 비교

이 메소드는 성능 최적화와 브라우저의 갱신 주기에 맞춰 애니메이션을 실행하는 반면, setInterval() 메소드는 일정한 시간 간격으로 콜백을 호출합니다.

setInterval() 메소드를 사용하면 브라우저의 갱신 주기와 관계없이 애니메이션을 실행하게 되므로, 화면이 끊기거나 부드럽지 않을 수 있습니다.

setInterval(() => {
  // 애니메이션 코드
}, 1000 / 60);  // 60fps로 설정, 이는 성능에 영향을 줄 수 있음

이 방법은 성능이 떨어질 수 있습니다.

정리

requestAnimationFrame() 메소드를 사용하면 애니메이션을 보다 효율적으로 구현할 수 있으며, 성능 최적화와 브라우저의 갱신 주기를 잘 활용할 수 있습니다.

특히 애니메이션 성능과 부드러움을 높이려면 이 메소드를 사용하는게 가장 적합한 방법입니다.

관련 글

자바스크립트 튜토리얼