requestAnimationFrame

그니·2023년 8월 1일
post-thumbnail

setInterval() 대신 requestAnimationFrame() 사용 권장 이유

  • setInterval() 은 브라우저가 실제로 화면을 그리는 지 여부와 관계없이 실행된다.
  • 앱을 화면에 띄우지 않은 백그라운드에서 계속 실행된다.
  • 다음 렌더링 사이클에 도달하기 전에 setInterval()에 등록된 콜백 함수가 실행된다.
    브라우저 렌더링과 setInterval
  • 반면 requestAnimationFrame() 은 브라우저가 다음에 그릴 프레임을 준비할 때까지 기다린 후 실행된다.

자바스크립트 웹 애니메이션


  • 간단하고 규칙적인 애니메이션 css로 요소의 좌표값, 스타일 크기 변화
  • 세밀한 조작 -> javascript로 스타일 속성을 변경.
  • javascript로 스타일 조정 시 css 보다 성능 낮음.

브라우저 렌더링 단계

브라우저 렌더링 단계
👉 Javascript: 애니메이션 및 기타 작업 스크립트를 수행 (DOM 생성)
👉 Style: CSS 규칙을 어떤 요소에 적용할 지 계산하는 프로세스 (CSSOM 생성)
👉 Layout: 브라우저는 DOM, CSSOM 을 결합하여 객체들의 위치와 크기 등을 계산하는 Render Tree 를 생성.
👉 Paint(re-draw): 브라우저는 Render Tree 를 사용하여 실제로 화면에 픽셀을 출력 (객체가 실제 화면에 그려지는 것을 의미)
👉 Composite: 브라우저는 화면에 출력되는 객체를 합성하여 최종 화면을 생성.
=> Javascript로 엘리먼트에 변화를 준다면 Javascript 코드를 실행 후 끝이 아닌, 렌더링 파이프라인 단계를 지나 화면에 그려진다.

브라우저 프레임

  • hz: 1초동안 모니터 화면의 출력 빈도 -> hz는 frame과 관련.
  • 영화 또는 애니메이션 -> 짧은 시간 간격에 이어지는 장면을 보는 것.
  • 각각의 장면을 frame이라 함.
    -> 특정 시간 내에 보여지는 frame의 개수 frame per second -> fps
  1. 웹 화면에 부드러운 애니메이션 움직임 효과를 주기 위해선 이 프레임 단위에 맞게 설계해야 함.
  2. 초당 60개의 프레임을 렌더링 -> (1000ms / 60fs) 간격으로 프레임 생성 필요.
  3. Javascript로 사용자에게 부드러운 애니메이션을 구현하려면 16.6ms 마다 코드를 호출 하는 식으로 구현.

타이머 함수의 문제점

  • 주어진 시간 내에 동작할 뿐 프레임을 신경 쓰지 않고 동작한다.
  • 프레임 단위로, 프레임 시작 시간에 맞춰 실행됨을 보장하지 못한다.
  • 약 16ms 간격으로 프레임 단위로 진행되어야 하는데, 브라우저가 다른 작업 수행으로 인해 지연되어 Javascript의 콜백 코드 부분이 단위 중간에서 호출된다.
    16ms 단위로 실행되는 타이머 함수
  • setInterval() 에 의해 등록된 Callback 함수가 이벤트 루프에 의해 실행될 경우 각 프레임의 시작 전에 올바르게 실행 되냐인듯

Javascript 실행에 의해 리플로우가 일어나 위 브라우저 렌더링 단계인

  1. 레이아웃
  2. 페인트
  3. 합성
    과정이 다시 일어나게 되는데,
  4. 자바스크립트의 호출 스택은 싱글 스레드이기에
  5. 프레임이 생성되지 못하고 누락되어 1프레임이 누락될 수 있다.

프레임이 깎이면 프레임 드랍으로 인하여 화면이 버벅인다.

requestAnimationFrame

  • 시스템이 프레임을 그릴 준비가 되면 애니메이션 프레임을 호출하여 애니메이션 웹 페이지를 보다 원할하고 효율적으로 생성 가능.
  • 실제 화면이 갱신되어 표시되는 주기에 따라 함수를 호출 -> 프레임 시작 시 실행되도록 보장 -> 밀림 현상 방지
    rAF가 동작하는 이미지
  • 각 프레임이 브라우저의 프레임 주기에 맞춰 일정한 시간 간격으로 렌더링 된다.
  • rAF 함수 실행 -> 다음 프레임이 그려지기 전 함수를 실행하도록 예약 -> 정확히 16.6ms간격으로 렌더링
  • 애니메이션 프레임을 페인팅 할 준비가 됐을 때 호출 -> 이전 setInterval 방식이 준비가 되지 않아도 페인팅을 요청하는 것과 대비 -> 보다 웹 브라우저에 최적화.
    -> 지연 및 블로킹 현상이 생기지 않아 보다 부드러운 애니메이션.

rAF 장점

백그라운드 동작 중지
1. setInterval 같은 경우 브라우저의 다른 탭 화면을 보거나, 최소화 되어 있을 시 계속 타이머가 돌아 콜백을 호출 -> 리소스 낭비.
2. rAF는 페이지가 비활성화 -> 페이지 화면 그리기 작업도 브라우저에 의해 일시 중지.
rAF 큐에서 처리
1. rAF 함수도 setTimeout 및 여타 이벤트 핸들러와 같이 "애니메이션 프레임"을 그리기 위한 콜백 함수를 등록, 비동기 Task로 분류하여 처리.
2. rAF는 일반적인 task queue가 아닌 animation frame 이라는 별개의 queue에서 처리.

별도의 큐에서 적재되어 이벤트 루프에 의해 꺼내지기 때문에
1. 실행이 뒤쳐지거나
2. 감소할수가 있다.!
업로드중..
👉 Task queue : 이벤트 콜백 함수, setTimeout 및 setInterval 비동기 콜백 함수 처리
👉 Task queue2 : Task queue 1에 있는 모든 콜백 함수들이 실행된 후 실행되어야 하는 다음 콜백 함수들
👉 Microtask queue : Promise 객체, Mutation Observer 객체를 처리. (가장 우선순위가 높음)
👉 Animation frames - rAF와 같이 브라우저 렌더링과 관련된 태스크 처리.

출처

0개의 댓글