CSS 애니메이션을 구현 할 때, 애니메이션 효과가 자연스럽지 못하고 끊기는 듯한 모습이 발생할 수 있다. 애니메이션을 최적화를 하기 위해서, 다시 말해 부드러운 애니메이션을 적용하기 위해서는 reflow와 repaint를 최소화 시켜야 한다.
리플로우(reflow) : 레이아웃 계산을 다시 하는 것을 말하며, 노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생한 경우에 한하여 실행된다.
리페인트(repaint) : 재결합된 렌더 트리를 기반으로 다시 페인트하는 것을 의미한다.
이러한 리플로우와 리페인트를 발생시키는 속성들을 아래에 소개하겠다. 아래에 소개하는 속성들의 변경을 가능한 줄임으로써 웹 페이지의 반응성 저하를 줄일 수 있다.
리플로우가 발생하는 속성
| 리플로우 | |||
|---|---|---|---|
| width | height | padding | margin |
| display | border-width | border | top |
| position | font-size | float | text-align |
| overflow-y | overflow | font-weight | left |
| font-family | line-height | vertical-align | right |
| clear | white-space | bottom | min-height |
리페인트가 발생하는 속성
| 리플로우 | |||
|---|---|---|---|
| color | border-style | visibility | background |
| text-decoration | background-image | background-position | background-repeat |
| outline-color | outline | outline-style | border-radius |
| outline-width | box-shadow | background-size |
리플로우와 리페인트가 발생하는 코드들 최대한 줄이기
표에 나와있는 코드들의 변경을 최대한 줄이면서 리플로우와 리페인트가 발생하는 것을 방지한다
3D transform 사용하기
transform은 부모 요소의 영향을 받지 않으면서 독자적으로 요소의 위치 및 확대, 축소, 회전이 가능한 css 요소이다. 그렇기 때문에 transform을 사용하면 브라우저에서 GPU(그래픽 처리 장치)를 사용하며 이것은 CPU에 부담을 덜어줄 수 있기 때문에 성능을 저하하지 않게 된다. 또 transform 3d의 경우에는 x,y,z 축으로 3차원상에서 이동할 수 있기 때문에 자연스러운 움직임을 구현해낼 수 있다.
인라인 스타일을 사용하지 않기
인라인 스타일은 HTML이 파싱될 때, 레이아웃에 영향을 미쳐 추가 리플로우를 발생시킨다. 또한 관심사 분리가 제대로 이루어지지 않으면 유지 보수가 힘들어 진다.
animation이 부여된 요소는 position : fixed, absolute 사용하기
애니메이션 효과는 많은 reflow 비용을 발생시킨다. position 속성을 fixed 또는 absolute의 값으로 주어, 지정된 요를 전체 노드에서 분리시켜 해당 노드에서만 reflow가 발생하도록 제한시킬 수 있다.
애니메이션 효과를 줘야 하는 요소에 position 속성이 적용이 되지 않았다면 애니메이션 시작 시 position 속성 값을 fixed 또는 absolute로 변경하였다가 애니메이션 종료 후 다시 원복시켜서 렌더링을 최적화 할 수 있다.