브라우저에서 화면을 그리기 위해서 일어나는 과정들은 변화가 일어났을 때 발생한다.
브라우저의 메인 스레드는 DOM 조작, 스타일 계산, 레이아웃 처리, 페인팅 등 다양한 작업을 수행한다. 메인스레드는 순차적으로 작업을 실행하게 된다. 그런데 만약 처리하는 도중에 시간이 많이 걸리는 작업이 발생한다면? 이전 렌더링이 완료되지 않았는데 또다른 애니메이션 요청이 들어온다면? 이전 작업이 중단되거나 끊기는 현상이 발생하고 사용자 경험이 떨어질 것이다.
requsetAnimaitonFrame
을 통해 화면이 변경되는 프레임의 횟수를 보장하여 부드러운 렌더링을 제공할 수 있다. 이 API는 리페인트
가 이벤트 루프에서 스케줄링 되기 직전에 실행된다.
브라우저 화면 상에 무언가를 렌더할 때, 위치를 계산하고 레이아웃에 영향을 주는 것을 '리플로우', 이 계산을 실제로 수행하여 재생성된 렌더 트리를 브라우저상에 그리는 것을 '리페인트'라고 한다.
1. requestAnimationFrame은 매개변수로 콜백 함수를 받는다.
2. 콜백 함수는 리페인트 이전에 실행된다.
requestAnimationFrame
은 일반적인 태스크 큐가 아니라 애니메이션 프레임 큐
에서 처리된다. 별도의 큐에서 적재되었다 이벤트 루프에 의해 꺼내지기 때문에 실행이 뒤쳐지는 현상을 감소할 수 있다.
setInterval으로도 주사율을 고려해서 구현할 수 있지만, setInterval은 브라우저가 최소화되거나 다른 탭을 보고 있을 때도 타이머가 돌기 때문에 리소스 낭비를 초래한다. 그에 반해 requestAnimationFrame
은 페이지가 비활성화 된 상태일 땐 함께 중지되기 때문에 리소스 낭비가 없다.
가장 중요한 점은, setInterval에서는 콜백 함수 호출 시간을 지정해줘야 하지만 requestAnimationFrame
에서는 모니터 주사율을 그대로 따르게 최적화 되어있다는 점이다.