개발 기술/사소하지만 놓치기 쉬운 개발 지식

[CSS] 왜 transform 애니메이션 성능이 좋을까? (with. GPU, Reflow)

by GicoMomg (Lux) 2023. 11. 28.

1. Left 애니메이션은 왜 끊길까?

  • transform, left 속성으로, 대각선 방향으로 움직이는 공 애니메이션을 만들어봤다.

See the Pen Animate with Translate and left by KumJungMin (@kumjungmin) on CodePen.



  • 보기에는 둘 다 잘 동작하는 거 같은데, 만약 JS에서 복잡한 연산을 실행하면 어떻게 될까?
  • gif를 보면 알 수 있듯이 JS에서 복잡한 연산을 하자, left 애니메이션이 잠시 끊기는 걸 볼 수 있다.



  • 그럼 두 애니메이션의 성능은 어떨까? [Chrome] > [성능]에서 성능을 측정해보았다.
  • transform 애니메이션의 경우 별다른 성능 이슈가 없는 것으로 보인다.


  • 그에 반해 left 애니메이션은 “누적 레이아웃 변경으로 사용자 경험이 악화”된다는 경고가 떴다.


🤔 그럼 어떻게 해야 left 애니메이션의 성능을 올리고, 애니메이션 끊김을 막을 수 있을까?

  • 답은 간단하다! left 속성을 transform으로 바꾸면 된다.
  • 그럼, 왜 transform 애니메이션은 끊김 현상이 없고, 성능 이슈도 없을까?
  • 이유는 transform 애니메이션이 GPU에서 작동하고, 리플로우(Reflow)가 발생하지 않기 때문이다.
  • 이번 시간에는 GPU와 리플로우 관점에서, transform 애니메이션의 성능이 좋은 이유를 알아보았다.



2. transform 애니메이션은 왜 성능이 좋을까?

1) GPU 관점에서 살펴보기

🤔 left 애니메이션은 CPU에서 처리하고, transform 애니메이션은 GPU에서 처리한다.
그리고 GPU 기반 애니메이션은 성능이 좋다고 한다.
그러면 CPU와 GPU는 어떤 차이가 있길래, GPU 애니메이션의 성능이 더 좋을까?

(1) CPU와 GPU의 특징

  • CPU와 GPU 차이는 아래 표를 보면 알 수 있는데, CPU는 논리적 연산에 최적화 되어있지만 GPU는 그래픽 처리에 최적화되었다.
종류 CPU (Central Processing Unit) GPU (Graphics Processing Unit)
장점 - 범용적인 연산에 최적화
- 복잡한 연산, 논리적인 처리, 순차적인 작업에 적합
- 그래픽 처리에 특화된 프로세서
- 수천 개의 작은 코어를 가지고 있어 대량의 병렬 연산에 적합
- 비디오 렌더링, 이미지 처리를 빠르게 처리할 수 있음
단점 - 한 번에 처리할 수 있는 작업의 양이 제한적
- 많은 양의 병렬 처리에는 적합하지 않음
- 남용시 성능 저하를 일으킴
- CPU 렌더링에 비해 정확성이나 품질이 낮음
  • CPU 기반 CSS 속성은 left, right, width, height 등이 있고,
  • GPU 기반 CSS 속성은 transform, opacity 등이 있다.

(2) GPU 애니메이션이 빠른 이유

  • CPU는 메인스레드 작업을 담당하고 순차적인 작업에 적합하다.
  • 그렇다보니, CPU가 다른 연산을 처리 중이면 CPU 기반 애니메이션은 동작이 멈출 수 있다.
  • 사용자 입장에서는 애니메이션이 끊기거나 멈추는 것처럼 보여 사용성을 해친다.
  • 그래서 그래픽이나 애니메이션 작업은 메인 스레드와 별개로, 병렬로 처리되는 게 좋다.

  • GPU는 병렬 작업에 최적화되어 있으며, 메인 스레드와 별개로 애니메이션을 처리할 수 있다.
  • 그래서 GPU로 애니메이션을 처리하면, CPU는 그래픽이 아닌 다른 계산을 처리할 수 있어 성능을 유지할 수 있다.
  • 결국 GPU 기반 애니메이션은 메인 스레드와 별개로 병렬 처리할 수 있어 성능이 좋다!



2) Reflow 관점에서 살펴보기

💡 left, right 등 CPU 기반 애니메이션은 reflow가 발생해 애니메이션 성능이 좋지 않다.
어? 그런데 reflow는 무엇이길래 성능에 영향을 주는 걸까?

(1) Reflow, 화면 레이아웃을 다시 그리는 작업!

  • reflow을 이해하기 위해선, 브라우저 렌더링 과정을 알아야한다.

단계 설명
Style 1. 유저가 브라우저에 입장하면, 네트워크에서 브라우저 리소스를 다운로드 받는다.
2. 그 다음, 리소스(HTML, CSS)를 파싱해서 각각 DOM 트리, CSSOM 트리를 만든다.
3. DOM 트리, CSSOM 트리를 결합해 Render Tree(렌더트리)를 만든다.
Layout 4. 브라우저는 생성된 렌더트리를 기반으로 노드의 크기나 위치를 계산한다.
Paint 5. 노드를 화면에 그리는 단계이다.
경우에 따라 화면에 그리는 작업을 몇 개의 레이어로 나눠 진행한다. (이 경우는 다음 섹션에서 설명)
Composite 6. 만약 레이어 분리가 일어났다면 레이어를 하나로 합친다.
  • 여기서 주목한 곳은 Layout인데, 왜냐하면 reflow가 이 Layout 을 다시 하는 걸 말하기 때문이다.
  • reflow가 발생한다는 건, 요소의 크기, 위치 계산을 다시 한다는 말이다.

💡 요소의 위치나 화면을 다시 그릴 수도 있지, 왜 이 작업이 성능에 영향을 주나요?

  • reflow는 DOM 요소의 기하학적 속성이 변경되거나, 브라우저 사이즈가 변할 때 발생한다.
  • 그리고 비용 큰 이유는, reflow가 발생하면 주변 요소의 위치나 크기에도 영향을 주기 때문이다.
  • 아래 이미지를 보면 알 수 있듯이, 형제 2의 너비가 변경되자 형제 3의 위치도 영향을 받았다.
  • 이처럼 reflow는 주변 요소의 위치나 크기에도 영향을 주기에 비용이 높다.
  • 또한 reflow가 발생하면, 재생성된 렌더트리를 기반으로 repaint(Paint 다시하기)도 한다;


💡 아하! 결국 left, right와 같은 속성으로 애니메이션을 만들면 reflow가 발생해,
주변 요소의 위치나 크기에 영향을 주고 Paint도 발생해서 성능이 안 좋은거구나!

  • 그러면 여기서 하나의 의문이 생긴다. GPU 애니메이션은 왜 reflow이 안 일어날까?
  • 그 이유는 GPU 애니메이션은 별도 레이어에서 처리되기 때문이다!

(2) 별도 레이어에서 처리된다고?

  • 브라우저는 Paint 단계에서 아래 태그나 속성을 만나면, 노드를 별도 레이어로 분리한다.
- 태그
<video></vide>
<canvas><canvas>

- CSS 속성
opacity
transform
will-change
  • 노드가 별도 레이어로 분리되면 다른 요소에 영향을 주지 않아 reflow가 발생하지 않는다.
  • 그리고 레이어는 CPU가 아닌 GPU에서 처리되기에 메인 쓰레드의 부담이 적어 성능이 보장된다.
  • 결국, transform 애니메이션은 별도 레이어에서 처리되므로, reflow가 발생하지 않는 것이다.



2. 마치며…

  • 이번 시간에는 transform 애니메이션 성능이 좋은 이유를 알아보았다.
  • 첫 번째 이유는 transform 애니메이션이 GPU를 사용하여 병렬 처리가 되기 때문이었고, 두 번째 이유는 별도의 레이어에서 처리되 Reflow를 발생시키지 않기 때문이었다.
  • 단, GPU 기반 애니메이션은 이처럼 성능이 좋다는 이점도 있지만 주의할 점이 있다.
  • 첫째, GPU 애니메이션을 남용하면 GPU 메모리 사용량이 증가해 메모리 리소스가 고갈될 수 있다.
  • 둘째, 레이어를 많이 만들면 GPU가 관리해야 할 레이어가 증가하여 성능 저하를 초래할 수 있다.
  • 셋째, 레이어를 합성하는 과정이 추가되면서 전체 렌더링 시간이 늘어날 수 있다. 따라서, GPU 애니메이션은 필요할 때만 적절히 사용하는 것이 중요하다.




+) 출처

반응형

댓글