CSS / JavaScript 애니메이션
@corinthioniaSeptember 11, 2024
Main thread vs Compositor thread
Main Thread
- 웹 페이지의 기본 작업을 처리하는 스레드
- HTML, CSS, JavaScript의 파싱과 실행, DOM 업데이트, 스타일 계산, 레이아웃 변경 등을 담당한다
- JavaScript의 실행과 DOM 조작은 메인 스레드에서 이루어지기 때문에, 복잡한 스크립트 실행은 페이지 렌더링에 영향을 줄 수 있다
Compositor Thread
- 브라우저의 렌더링 엔진에서 애니메이션과 같은 그래픽 작업을 처리하는 별도의 스레드
- 주로 화면에 그려지는 요소들의 레이어를 관리하고, 애니메이션, 변형(transform), 오버레이 등 화면에 출력되는 것을 담당한다
- Compositor Thread는 GPU 가속을 활용하여 애니메이션을 부드럽게 처리할 수 있다
CSS 애니메이션 vs JavaScript 애니메이션
애니메이션을 구현할 때에는 Reflow/Repaint 과정을 최소화하는 것이 중요하다!
CSS 애니메이션
-
간단한 애니메이션을 구현하는 경우 사용한다
-
CSS의
transform
,animation
속성 등을 이용하여 구현한다@keyframes move-right { from { transform: translateX(0); } to { transform: translateX(100px); } } .box { animation: move-right 1s infinite; }
-
CSS 애니메이션은 브라우저가 GPU(그래픽 처리 장치)를 사용하여 처리하기 때문에 성능적으로 좋다
-
또한
transform
,opacity
등의 속성을 사용하여 애니메이션을 구현하면 Reflow와 Repaint 없이 Composite 단계에서만 처리되기 때문에 성능적으로 좋다 -
CSS로 간단히 구현할 수 있는 애니메이션을 JavaScript로 구현하면 Reflow/Repaint가 발생할 수 있어 성능적으로 좋지 않다
- CSS 애니메이션은 Main thread가 아닌 별도의 Compositor thread에서 그려지기 때문에 Main thread에서 작업하는 JavaScript보다 효율적이다
-
복잡한 애니메이션 구현은 어렵다
JavaScript 애니메이션
- CSS로 처리하기 어려운 복잡한 애니메이션을 구현하는 경우 사용한다
- JavaScript의
setInterval
또는requestAnimationFrame
을 사용하여 구현한다
let start = null;
const element = document.getElementById('element');
function step(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
element.style.transform = `translateX(${progress / 10}px)`;
if (progress < 2000) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
requestAnimationFrame
을 사용하면 프레임 단위로 세밀하게 애니메이션을 조절할 수 있다- JavaScript 애니메이션은 CPU를 사용하여 렌더링 되므로 복잡한 애니메이션에서는 성능이 떨어질 수 있다
requestAnimationFrame
API를 사용하거나 GPU 가속을 사용하는 라이브러리를 이용하면 성능을 향상시킬 수 있다
Reference
← 이전 글브라우저 렌더링 과정
다음 글 →상태 관리 라이브러리