FrontendPerformanceCSSAnimation

애니메이션 효과 주는데 버벅인다.

·7 min read

css 가지고 애니메이션 효과주고 노는데,

효과가 점점 중첩되고, 전환 효과 많아지다 보니깐 버벅이기 시작한다.

최적화 하는 과정중에 나름 인사이트를 좀 얻어서 오늘의 주제는 렌더링이다.

브라우저가 화면을 그리는 법

브라우저는 크게 Layout -> Paint -> Composite 순서로 그림을 그린다.

Layout(Reflow): 요소의 크기와 위치를 계산한다.(ex: width, height, margin 변경)

Paint(Repaint): 계산된 위치에 픽셀을 그린다.(background-color, border 변경)

Composite(합성): 'Paint'된 여러 레이어를 순서대로 합쳐 최종 화면을 만든다.

렌더링마다 가격이 다르다.

CSS 속성은 서로 다른 비용을 가진다.

예를들어 left를 바꾸는건 Layout 연산이다.

즉 left 위치 하나만 바꾸더라도 Layout -> Paint -> Composite 연산이 들어간다는 것이다.

left와 비슷한 기능을 하는 translateX는 Composite 연산이다.

즉 결과는 같은데, 연산 측면에서 translateX를 쓰는게 더 효율적이라는 것이다.

웹도 GPU 쓴다.

Layout과 Paint 연산에서는 CPU 연산이 들어간다.

다만 Composite 연산에서는 GPU 가속을 사용하는데

translate가 더 빠른 이유는 연산 하드웨어 자체가 다른점도 있다.

이게 가능한 이유는 우리가 웹 화면을 그린다는 것은 하나의 도화지에 그림을 그린다는 건데,

배경과 캐릭터 그렸는데 left로 캐릭터 옮긴다고 배경도 새로 그린다고 생각하면 느리다.

그래서 효율적인 연산을 위해 컴포지터 레이어라는 영역이 추가 된다.

transform, opacity, will-change 등... 움직이거나 변화를 주는 효과를 특정 요소에 적용하면

컴퓨터는 '아 이건 곧 움직이겠구나'하고 별도로 해당 요소를 컴포지터 레이어에 올려버린다.

배경을 그린 종의 위에 투명한 레이어지를 하나 올리고 거기다 캐릭터를 그리고 움직이는 방식이다.

물론 애네들도 만능은 아니라서 레이어가 많아질수록 해당 레이어를 관리하기 위해 GPU 메모리도 과다하게 사용된다.

즉 적용 시킬 범위나 요소들도 선택이 필요하다는 것이다.

그림자와 blur는 비싸다.

애니메이션 효과에서 광원 효과를 낼 때 그림자와 blur를 종종 사용한다.

다만 기본적으로 픽셀을 흐리게 하는 것은 복잡한 픽셀 계산을 동반한다.

특히나 기본적으로 CPU 연산을 기본으로 하기에 연산 속도 체감이 더더욱 잘된다.

애니메이션은 시간이다.

부드러운 효과 또는 시간별 반복되는 효과를 위해서 setInterval 을 가져다 쓰는 경우가 있다.

문제는 시간을 대상으로 하다보니깐 브라우저의 렌더링 주기랑 동기화가 안되면서 애니메이션이 지속되면서 효과와 로직의 순서가 꼬이는 경우가 있다.

다른 문제로 탭이 비활성화 되도 애는 시간 계산한다고 계속 백그라운드에서 CPU 연산 갉아먹으면서 버틴다는 것이다.

그런 당신을 위한 선택 requestAnimationFrame(rAF)

애니메이션을 위해서 프레임 단위로 실행을 제어할 수 있는 rAF를 쓰자.

브라우저 렌더링 사이클에 맞춰 실행되며 탭이 비활성화 되면 아예 실행되지 않아 CPU 낭비를 막는다.

이거 곧 바뀜 will-change

아까 transform과 같이 곧 바뀔꺼 같으니 레이어 올려서 GPU 가속으로 처리하고자 한다면 will-change 속성을 사용 할 수 있다.

브라우저에게 이 요소 곧 바뀌니깐 미리 최적화 하라고 알려주는건데,

브라우저는 이 속성을 받으면 해당 요소를 '별도 레이어'에 미리 분리해서 준비한다.

다만 일단 켜두면 좋겠지 라는 심정으로 요소 이것저것 올리다보면 문제가 생기는데

GPU에 올려 준비하는 만큼 VRAM을 사용한다.

will-change가 적용되면 애니메이션 실행 안되도 계속해서 별도 레이어로 존재한다.

즉 크롬이 램 먹는 괴물이라면 우리는 그 괴물을 진화시켜 아무나 걸려라 괴물로 만들 수 있다는 것이다.

물론 쓰고 반납하는 기능이 있으니

잘 활용했으면 자원은 잘 반납하자.

마무리

웹이 좀 가볍기도 하고, 사람들 램, CPU 정도는 적당히 있으니 요즘 최적화 신경 안쓰고 막 만드는 경향이 있긴 한데,

웹 3.0 시대에서는 좀 더 인터랙티브한 웹이 등장할 것 같으니,

최적화와 렌더링을 신경쓰면서 만들자.

← Previous
이미지 생성, Stable diffusion
Next →
쉽게푼_MCP