본 문서는 원작자의 동의를 얻어 원문의 의미를 해치지 않도록 번역하였으며, 이해를 돕기 위한 Chrome DevTools 활용 방법을 추가했습니다.

CSS 애니메이션의 성능 비교

웹 페이지에서 애니메이션을 어떻게 구현하고 계신가요?

JavaScript animation? CSS animation?

웅성웅성뭐야
뭐라는ㄱ..큰큰

라이브러리를 활용해 JavaScript 애니메이션을 구현할 수 있지만, 현재의 native CSS도 다양한 애니메이션을 구현할 수 있습니다.
그 중 성능 향상에 도움되는 CSS 애니메이션 구현 방식을 소개합니다.

👀

CSS 애니메이션은 일부 속성에 의존합니다.

  • position : absolute / relative
  • transform
  • opacity
  • left, right, top, bottom 등등…

애니메이션의 속성이 다른 두 개의 테스트 결과를 살펴봤습니다.

translatetop/left
[참고 예제] https://codepen.io/vpsk/pen/qBBGNGZ[참고 예제] https://codepen.io/vpsk/pen/vYYwKwm

😮
레이블이 없었더라면 차이를 전혀 못느꼈을 거에요.
이 결과를 보면, 다른 방식이지만 보여지는 것은 동일하다는 것을 알 수 있죠.
하지만 Chrome의 DevTools로 측정을 해보면 특별한 차이를 발견할 수 있습니다. 😏

성능 측정 결과의 이해를 돕기 위해, 웹 브라우저의 렌더링 방식을 간단히 살펴보겠습니다.
웹 브라우저는 UI를 다음과 같은 방식으로 생성합니다.

  1. Recalculate Style
    요소에 적용할 스타일을 계산.
  2. Layout
    요소의 레이아웃을 생성하고, 화면에 배치.
  3. Paint
    생성된 모든 레이아웃에 픽셀을 추가. GPU는 필요에 따라 생성한 레이어의 비트맵을 사용해 화면에 렌더링.
  4. Composite Layers
    생성한 레이어 계층을 합성. 이 계층을 내려다보면 모든 요소가 고유한 위치(복합 계층)를 갖는 완전한 웹 페이지로 보여집니다.

Composite Layers 생성은 CPU가 애니메이션을 처리하기 위해 GPU와 통신하는 단계입니다.
transformopacity와 같은 속성을 사용하면, CPU 대신 GPU를 사용해 웹 브라우저가 애니메이션을 수행할 수 있도록 할 수 있습니다.

GPU를 사용하면 부드러운 애니메이션을 수행하는 것에 도움이 되나요?
 
GPU는 애니메이션을 처리하는 또 다른 작은 기계며, 많은 UI 계산을 처리할 수 있습니다.

Composite Layers 생성이 트리거되면 새 레이어를 생성합니다. 이것은 UI 요소의 애니메이션과 아닌 일부를 나눠, 다시 렌더링 하지 않기 위해서입니다.

다음 그림을 보면, 빨간 원은 모두 같은 계층에 있습니다. 하지만 이 레이어를 transform 속성으로 회전(rotate)하면 해당 요소가 레이어로 생성되어 부드러운 애니메이션을 제공합니다.
GPU는 이 렌더링 객체 트리를 메모리에 유지하고, 다시 렌더링 하지 않는 레이어를 위에 얹을 수 있습니다.

그러나 top/left 애니메이션은 동일한 레이어를 반복해서 렌더링합니다. 이 동작을 확인하면 topleft의 속성이 모두 레이아웃에 영향을 주며 repaint, composite 작업이 다시 발생하는 것을 알 수 있습니다.

transfrom (좌) (우) position absolute with left and top

이렇게 translate와 top/left 애니메이션은 보여지는 것은 동일하지만 성능 측면에서는 명확한 차이가 있습니다.

Performance 패널에서 두 속성을 비교해 봤습니다.

translatetop/left

하나의 task를 선택해서 수행하는 활동을 비교했습니다.
top/left의 경우 메인 스레드에서 Layout , Painting, Recalculating Style을 계속 수행중이고,
translate은 Composite layer 작업만 수행하고 있습니다.

GPU에서 애니메이션을 처리하는 덕분에 메인 스레드를 자유롭게 유지할 수 있습니다. 이런 방식으로 웹 페이지의 성능을 향상 시키고, 메인 스레드는 렌더링 레이아웃에 집중할 수 있게 됩니다.

transfrom (좌) (우) position absolute with left and top

이 성능 메트릭 그래프는 메인 스레드가 Layout, Recalculating Style 재계산이 얼마나 많이 발생하는지 살펴볼 수 있습니다. 이 그래프는 발생하는 UI 변경 사항을 지속적으로 반영합니다.

아니 근데 저런 것들은 어떻게 확인하는 거죠?

 
☝️
 
제가 준비해봤습니다.
지금까지 살펴본 내용을 DevTools를 통해 직접 확인하세요!

DevTools 활용 방법

준비물 : Chrome DevTools, CSS Animation SamplePage

Rendering

CSS Animation SamplePage를 열고 DevTools의 더보기 메뉴 > More tools > Rendering 메뉴를 선택하면 렌더링 관련 부분을 확인할 수 있어요.

 
 체크 포인트

  1. Paint flashing : repaint가 되는 영역을 녹색으로 표시합니다.
  2. Layout Shift Regions : layout 변화가 발생한 곳을 파란색으로 표시합니다.

두 애니메이션의 layout, paint가 다르게 동작하는 것을 확인할 수 있습니다.

translatetop/left

두 애니메이션의 동작 방식이 다른 것은 확인했고, 다음의 방법으로 조금 더 상세하게 알아볼 수 있어요.

Layers

CSS Animation SamplePage를 열고 DevTools의 Layers 패널로 확인합니다.

비교 포인트

  1. 웹 페이지의 레이어를 확인합니다.
    (translate에 레이어가 생성되어 애니메이션 요소만 움직이고, topleft는 전체 화면에서 동작합니다.)
  2. Paint Count를 확인합니다.
    (애니메이션이 동작하는 레이어를 선택하고 하단의 Details를 보면, translate는 count가 증가하지 않는데, topleft는 count가 계속 증가합니다.)
  3. Paint Profiler를 보면 더욱 상세한 내용을 살펴볼 수 있어요.
translatetop/left

다른 두 애니메이션의 레이어 구조와 사용되는 memory, paint count 등의 정보를 확인할 수 있습니다.
다음 소개드릴 도구를 사용하면 두 애니메이션 성능을 더욱 쉽게 비교할 수 있습니다.

Performance monitor

CSS Animation SamplePage를 열고 DevTools의 더보기 메뉴 > More tools > Performance monitor 메뉴를 선택하면 렌더링 관련 부분을 확인할 수 있어요.

translatetop/left

직접 확인할 수 있어서 씬난 분들을 위해 또 다른 예제 페이지를 준비했습니다.
다음 페이지도 동일한 방법으로 비교해보세요~!
😉

마무리

속성에 따라 웹 페이지에 미치는 영향을 알고, 애니메이션 구현에 잘 활용할 수 있길 기대합니다.
CSS 속성이 발생시키는 영향은 csstriggers.com에서 자세히 살펴보실 수 있어요.

Chrome DevTools 사용에도 조금이나마 도움되었길 바래봅니다.

😎

참고 자료


5개의 댓글

박진호 · 2020년 6월 5일 10:56 오전

좋은 글 감사합니다. CSS 성능에 대해서 관심이 많은데 많은 도움이 될 것 같습니다. ^^

CSS · 2020년 6월 24일 5:48 오후

개발자툴로 렌더링 체크 해봤는데 예시처럼 안뜨네요..새로고침하면 다른 곳은 표시 되는거 보니 정상작동은 하는데
top/left 와 translate 차이가 안납니다..!

    WIT Manager · 2020년 7월 1일 5:42 오후

    코드펜에서 스크립트가 제대로 동작하지 않아 링크를 변경해두었습니다. 미처 확인하지 못해 죄송하며 제보 감사드립니다.

통신보안생활화 · 2020년 8월 4일 11:10 오전

굳이네요

김재환 · 2020년 8월 8일 5:35 오후

좋은 글 감사합니다! 궁금한 점이 있습니다. 드랍 메뉴를 만들 때, jQuery로 slideToggle로 만드는 것과 CSS로 기능을 만들고 스크립트로 addClass로 만드는 것 중 성능차이가 있을까요? 테스트를 안해보고 이런 댓글 남겨서 죄송합니다.;; 조만간 테스트 해봐야겠네요!

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다