requestAnimatonFrame??

HoJeong Im·2022년 1월 23일
0

FrontEnd

목록 보기
2/4

개요

  • 시각적인 update 코드를 작성시, 습관적으로 setTimeout, setInterval을 쓰던 상황을 피하고 느려지는 현상을 겪음

developer google com를 살펴보면,

  • 화면에서 시각적 변화가 발생하고 있을 때 => 개발자는 브라우저에서 정확한 시간(프레임 시작 시)에 작업을 수행하길 원함!

  • JS가 프레임 시작 시 실행되도록 보장하는 유일한 방법 = requestAnimationFrame

왜 setTimeout, setInterval은 사용하면 안 되는가?

  • 콜백이 프레임에서 특정 시점(종료 시)에 실행되고, 종종 프레임이 누락되어 버벅거림 현상이 발생할 수 있습니다

  • ex) 장치에 최적화된 프레임 속도로 실행되지 않는 문제, 프레임을 빠뜨리는 문제, tab이 활성 tab이 아니거나 애니메이션이 이 프레임을 벗어난 경우에도 계속 실행되는 문제

mdn Timeouts and intervals

  • 간단한 DOM 애니메이션은 CSS Animation으로 작성하자

    • why? JS가 아닌 브라우저 내부 코드로 직접 계산되기 때문에 속도가 더 빠름
    • 더 복잡한 작업, DOM 내에서 직접 액세스 할 수 없는 객체(2D Canvas API, WebGL)를 포함하는 경우, requestAnimationFrame()이 더 나은 옵션

왜 window.requestAnimationFrame을 써야하는가?

  • 브라우저가 다음에 디스플레이를 다시 표시하기 전, 지정된 코드 블록을 실행해 애니메이션이 실행되는 환경에 관계없이 => 적절한 프레임 속도로 실행될 수 있도록 함

  • window.requestAnimationFrame() : 브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 repaint가 진행되기 전 해당 애니메이션을 업데이트하는 함수를 호출하게 함

  • 사용 방법

window.requestAnimationFrame(callback);
  • 이것을 이해하려면? 브라우저 렌더링 과정부터 알아봅시다

Browser Rendering Process

  • 현재 사용자 작업과 관련된 콘텐츠 표시의 우선순위를 지정

  • 빠른 웹 환경을 제공하려면 브라우저가 많은 작업을 수행해야 함

  • 연속 루프에서 실행되며 이상적인 속도는 60 frame

  1. 객체 모델 생성(Constructing the Object Model)
  • 브라우저가 페이지를 렌더링하려면 먼저 DOM 및 CSSOM 트리를 생성해야 함

  • DOM (Document Object Model) :

  • CSSOM (CSS Object Model) :

  • css stylesheet를 처리하는 데 0.2ms가 걸리고 페이지에 있는 요소 7개가 영향 받는다고 볼 수 있음 => 그런데 CSSOM, DOM은 서로 독립적인 데이터 구조임
  1. 렌더링 트리 생성, 레이아웃 및 페인트(Render-Tree Construction, Layout, and Paint)
  • CSSOM, DOM 트리는 결합해 렌더링 트리를 생성 (표시되는 각 요소의 레이아웃을 계산하는 데 사용되고 픽셀을 화면에 렌더링하는 페인트 프로세스에 대한 입력으로 처리됨)

  • reflow : layout 단계 => 표시할 노드와 해당 노드의 스타일을 계산한 후, 기기의 뷰포트 내에서 이러한 노드의 정확한 위치와 크기를 계산하는 것

  • paint : Raster화 => 렌더링 트리의 각 노드를 화면의 실제 픽셀로 변환하는 마지막 단계

  • 문서의 크기, 적용된 스타일 및 기기에 따라 렌더링 트리 생성, 레이아웃 및 페인트 작업을 수행하는 데 필요한 시간은 달라질 수 있음

  • ex) 문서가 클수록 브라우저가 수행해야 하는 작업도 더 많아지고, 스타일이 복잡할수록 페인팅에 걸리는 시간도 늘어남

requestFrame 기본 사용법

  • 매개변수 timestamp : requestAnimationFrame이 실행되기 시작한 이후의 시간을 나타내는 timestamp 제공 가능

    • 장치 속도에 관계없이 특정 시간과 일정 속도로 작업을 수행할 수 있으므로 유용

let startTime = null, currentTime = null;

function draw(timestamp) {

  if(!startTime){
  	startTime = timestamp;
  }
  
  currentTime = timestamp - startTime;
  
  requestAnimationFrame(draw);
 
}

draw();

Reference

mdn requestAnimationFrame

developers google web dev

profile
꾸준함이 제일 빠른 길이었다

0개의 댓글