FrontEnd/Vue

[Vue] requestAnimationFrame

Grace 2023. 4. 25. 13:31

requestAnimationFrame() 는 브라우저에서 작동하는 애니메이션을 알려주고 다음 리페인트 진행 전에 해당 애니메이션을 업데이트하는 함수를 호출하게 합니다. 이 메서드는 리페인트 이전에 실행할 콜백을 인자로 받습니다.

리페인트 ?
리페인트란 리플로우 과정이 끝나고 재생성된 레이아웃 트리(렌더 트리)를 다시 레이어에 그리는 작업을 말합니다.
여기서 리플로우는 DOM 노드의 레이아웃 변경 시 영향을 받는 모든 노드의 수치를 다시 계산하여 레이아웃 트리(렌더 트리)를 재생성하는 작업을 의미합니다. css에서 width, height 같은 레이아웃에 영향을 주는 속성을 말합니다.
리페인트를 발생하게 하는 속성은 css에서 시각적으로 보여지는 모든 속성이며 이 외에도 레이아웃에 영향을 주는 것은 아니지만 시각적 요소가 바뀌는 경우입니다.

렌더링 속도는 순차적으로 진행되며, 각각의 렌더링 과정들은 반드시 전 단계의 데이터가 필요합니다. 만약 전 단계에서 변화가 일어나면 다음 단계에 모두 영향을 미칩니다.

화면에 새로운 애니메이션 업데이트가 준비될 때에 이 메서드를 호출해주는 것이 좋습니다. 브라우저가 다음 리페인트를 수행하기 전에 호출된 애니메이션 함수를 요청합니다. 대부분의 최신 브라우저에서는 성능과 배터리 수명 향상을 위해 requestAnimationFrame() 호출이 백그라운드에서 중단됩니다.

모든 이전 콜백의 작업 부하를 계산하는동안 지나갔음에도 불구하고 단일 프레임에서의 다중 콜백은 각각 동일한 타임스탬프를 받습니다.

requestAnimationFrame() 은 setInterval 처럼 속도를 조절할 수는 없습니다. requestAnimationFrame()는 브라우저의 리소스 & 컴퓨터의 CPU성능을 고려하여 초당 실행횟수가 결정되기 때문입니다.(기본 60FPS, 1초에 60번)

setInterval의 경우에 애니메이션을 동시에 여러 번 호출하면서 만약 리페인트 후에 setInterval이 실행되면 애니메이션이 누락되어 애니메이션이 꼬여 버벅거리고 프레임이 끊기는 현상이 발생하는데 requestAnimationFrame()애니메이션(화면 렌더 변화) 구현에 최적화된 함수이므로 실행되는 환경에 관계없이 적절한 프레임 속도로 실행되며, 탭이 활성화되지 않은 상태이거나 애니메이션이 페이지를 벗어난 경우에도 계속 실행되는 기존의 문제점을 해결할 수 있습니다.

예시 코드 (실시간으로 시간이 반영되는 시계)

<script setup lang="ts">
...
const clock = ref();

function updateClock() {
  const now = new Date();
  const hours = now.getHours(); // 시간
  const minutes = now.getMinutes().toString().padStart(2, '0'); // 분

  clock.value = `${hours}:${minutes}`; // value 변경

  requestAnimationFrame(updateClock); /* 2. 변경된 시간을 리페인트 전에 애니메이션으로
                                          리페인트 렌더 하도록 계속해서 함수 실행 */
}

requestAnimationFrame(updateClock); /* 1. 컴포넌트에 마운트 되면 리페인트 전 실행하도록
                                          rAF 함수 실행 */
</script>

<template>
...
<span>{{ clock }}</span>
...
</template>

'FrontEnd > Vue' 카테고리의 다른 글

[Vue-Cal] Vue.js 캘린더 라이브러리  (0) 2023.07.03
[Vue-Query] persistQueryClient  (0) 2023.04.24
[Vue-Query] useMutation  (0) 2023.04.20
[Vue-Query] useQuery  (0) 2023.04.20
[Vue-Query] @tanstack/vue-query  (0) 2023.04.20