애니메이션의 과정은 결국 브라우징 렌더링 과정에서의 Layout 단계와 연속적인 Paint단계에서 성능저하가 발생한다.
애니메이션의 성능을 높이는 방법
1. Layer 구성하기
Layout 단계에서 div의 style 속성이 무엇이냐에 따라 별도의 layer가 지정되거나 layout계산이 되기도 한다.
이렇게 나뉜 layer들은 layout의 계산이나 Paint없이 병합을 통해서 새로운 화면을 구상할 수 있다.
출처. http://blog.dotify.fr/interactive-video-part-2-developing-the-player-with-the-new-as3-api/
브라우저는 다음과 같은 상황에서 DOM을 별도의 Layer로 구성한다.
- 3D(translate3d, preserve-3d)나 perspective transform을 사용하는 경우
- VIDEO, CANVAS 태그를 사용하는 경우
- Flash나 ActiveX를 사용하는 경우
- CSS Animation, CSS filter를 사용하는 경우
- 자식엘리멘트가 Layer로 구성되어 있는 경우
- z-index가 낮은 형제 엘리멘트이거나 layer로 구성되어있을경우 해당 엘리먼트도 layer로 구성됨
이렇듯 레이어가 분화되면 Layout 단계와 Paint단계의 계산이 연속적으로 발생하게 되므로 레이어를 병합하는 과정을 통해
성능 향상을 이끌어 낼수 있다.
2. GPU 가속을 사용하기
GPU 가속은 브라우징 렌더링 과정에서 composite Layer방식으로만 동작한다. 각각의 layer를 GPU메모리에 bitmap형태의 texture로 넣어줘서 실제 composite layer를 작업할 때에는 GPU의 메모리에서 관련작업을 진행한다. 따라서 관련된 작업의 Layout 과 Paint 작업이 없어지게 된다. 반복적인 layout, paint단계가 없어지므로 성능 향상이 확실하다.
다음 style이 적용되면 브라우저는 GPU에 해당 엘리먼트 영역(Layer)을 메모리에 texture로 저장한다.
- -webkit-transform : translate3d
- -webkit-transform : translateZ
- -webkit-transform : rotate3d
- -webkit-transform : scale3d
- -webkit-transform-style : preserved-3d
단점
- 무분별한 GPU의 사용은 브라우저의 동작을 느리게 만는다.
- 저사양의 폰에서 하드웨어의 가속은 폰동작을 느리게한다.
3. 애니메이션 동작시 Layout 계산을 발생하게 하는 스타일이나 메소드를 사용하지 말것
엘리먼트의 크기나 위치를 변경하는 작업을 발생하게 하면서 애니메이션 동작을 한다면 layout계산이 함께 들어가므로 부드러운 애니메이션을 기대하기 어렵다.
CSS 애니메이션
일반적으로 간단한 메뉴이동이나 버튼의 전환과 같은 애니메이션들은 CSS의 tranform의 translate을 통해 처리할 수 있다. GPU가속을 통해서 layout, paint작업들을 생략할 수 있기 때문이다. 반면 JS로 엘리먼트들의 이동을 묘사하려면 setInterval을 통해서 style.width, style.height등 layout을 발생시키는 작업을 할 수 밖에 없다. 따라서 애니메이션의 성능이 확실이 낮아진다.
이외에도 장점은 다음과 같다.
- 반응형으로 웹을 구성하기 좋다. 미디어 쿼리를 이용하면된다.
- 외부 라이브러리를 필요로하지 않는다.
- CSS자체가 선언형이기 때문에 어떤요소가 애니메이션을 가져아한다는 직관적인 표현이 된다.
- 메인스레드가 아닌 별도의 컴포지터 스레드(Compositor Thread)에서 그려지기 때문에 메인스레드에서만 작업하는 JS보다 훨씬 효율적이다. → GPU가속을 사용하기 때문이다. 레이어를 움직이고 합성하는 과정에서 애니메이션을 만들어 버린다.
JS 애니메이션
CSS로 처리하기에는 훨씬 복잡하고 무겁고 세밀하게 처리해야하는 애니메이션들을 다룬다. 바닐라 JS는 굉장히 많은 layout계산과 paint를 반복하기 때문에 비효율적이고 사람들의 눈에 가장 부드러운 60fps가 유지되지 않는다. 이때문에 RAF(RequestAnimationFrame)이 등장했고 동일한 구현방식으로 60fps를 달성시킬 수 있었다. 이외에도 다양한 외부 라이브러리들이 있다. (Velocity.js 와 GSAP)
JS가 가지는 장점은 다음과 같다.
- 브라우저 호환성이 뛰어나다. 렌더링 엔진의 경우 브라우저 마다 달라 구현이 안되는 경우들이 있는데 JS 애니메이션은 호환성에 구애받지 않는다.
- GPU를 통한 하드웨어 가속을 제어할 수 있다. CSS 애니메이션의 경우 특정 속성에 의한 GPU가속이 됨으로서 저사양의 컴퓨팅인 경우에 성능 하락을 발생시킬 수 있으나 이를 막을수 있다.
- 요소의 스타일이 변하는 순간마다 제어가 가능하기 때문에 애니메이션의 세밀한 구성이 가능해진다.
참고
github.com/baeharam/Must-Know-About-Frontend/blob/master/Notes/frontend/css-js-animation.md
d2.naver.com/helloworld/5237120
sculove.github.io/blog/2013/12/05/animation-for-performance/
'FrontEnd' 카테고리의 다른 글
Next js - [window is undefined 에러] (0) | 2021.02.27 |
---|---|
CD와 CI (0) | 2021.01.14 |
모듈 번들러와 트랜스파일러 (0) | 2021.01.14 |
BOM & DOM (0) | 2021.01.13 |
자바스크립트 엔진이 코드를 실행하는 과정 (0) | 2021.01.13 |