효율적인 애니메이션: CSS vs. JavaScript

Kyungs·2021년 11월 22일
0

JavaScript

목록 보기
2/11
post-thumbnail
post-custom-banner

애니메이션 구현 방식

웹 브라우저에 애니메이션을 구현하는 방식에는 여러가지가 있다. CSS에서 transform, transition 속성을 부여할 수도 있고, JavaScript에서 setTimeout(), setInterval(), requestAnimationFrame() 등의 메소드를 사용할 수도 있다. 애니메이션이란 정해진 시간 내에 수 많은 프레임을 그려내는 작업이므로 컴퓨터의 성능에 크게 의존할 수 밖에 없고, CSS와 JavaScript의 "animation processing" 방식을 고려하여 기능을 구현해야 할 필요가 있다.

JavaScript 애니메이션

JavaScript에서는 비동기 요청을 통해 애니메이션을 구현할 수 있다. setTimeout()이나 setInterval()을 사용하여 특정 시간이 지난 후에, 또는 특정 시간마다 애니메이션을 실행시킬 수 있고 (예: 특정 시간마다 한 컴포넌트의 left, right 등의 속성을 변경), requestAnimationFrame()을 사용하여 매 초마다 60프레임을 (또는, 모니터 주사율에 따른 프레임 수를) 그리도록 하여 매우 부드러운 애니메이션을 그려줄 수도 있다.

위 방법들은 모든 애니메이션 프레임마다 브라우저가 컴포넌트의 기하 구조를 계산해주어야 하고(reflow), 계산을 통해 얻어진 모양을 그려주어야 한다(repaint). 이러한 reflow/repaint는 CPU에서 실행되며, 다른 모든 JavaScript 작업을 실행해야하는 CPU에게는 큰 부담이 아닐 수 없다.

CSS 애니메이션

CSS를 이용한 애니메이션은 CPU를 사용하는 방식과, GPU에게 맡기는 방식으로 나뉜다. 애니메이션 기능을 오로지 GPU에게 맡긴다는 것은 기하 구조를 계산하고 그려주는 reflow/repaint 과정을 CPU에서 거칠 필요가 없다는 뜻이다.

  • top, left 값을 수정하여 구현하는 애니메이션: reflow/repaint 필요!
    - 브라우저 화면의 크기에 영향받는 vh, vw 등의 속성을 top, left 값에 사용할 수 있으므로, reflow/repaint 과정이 필요하다.
  • transform, opacity 값으로 얻는 애니메이션: reflow/repaint 불필요!
    - 컴포넌트가 위치한 환경과 관련이 없는 속성들이다. GPU에게 애니메이션이 넘겨진다.

CPU vs. GPU

아래 언급된 참고 자료 중 한 사이트에서 JavaScript vs. CSS 애니메이션 성능을 비교하는 간단한 실험을 해볼 수 있었다. 아래와 같은 애니메이션을 JavaScript와 CSS로 구현하여 "Toggle"버튼만 누르면 애니메이션 진행 방식을 바꿀 수 있었다.

아래 그림은 크롬 개발자도구의 "Performance" 탭에서 얻어진 데이터 그래프이다. 약 4초 즈음에 "Toggle" 버튼을 눌러 CSS 방식에서 JavaScript 방식으로 변경하였는데, 아래 그래프에서 볼 수 있듯이 CPU의 사용량이 갑자기 생기는 것을 볼 수 있다.

결론: CSS의 transform, opacity를 최대한 사용하자

위에서 언급했듯이 CPU는 JavaScript의 모든 작업을 실행해야하고, 초당 수 많은 프레임을 계산하고 그려내야하는 애니메이션 작업까지 진행하게 된다면 부담이 될 수 있다. CSS의 transform, opacity 속성으로도 충분히 많은 애니메이션을 구현할 수 있고, 병렬 처리에 특화된 GPU에게 애니메이션을 맡길 수 있다면 보다 더 효율적으로 덜 끊기는 애니메이션을 구현할 수 있다.

참고 자료

MDN Web Docs: CSS and JavaScript animation performance
Website performance and laggy animations: GPU vs CPU
CSS GPU 애니메이션 제대로 하기

post-custom-banner

0개의 댓글