✍️ 3D transform을 사용하는 이유

기본 transform을 사용하지 않고 3d transform을 사용하는 이유는 간단하게 2d 이상의 다이나믹한 animation을 기대하기 때문도 있고 후반에 이야기할 animation을 사용할 때 발생하는 문제점을 보완하기 위해서도 있다.

우선 3d transform에 대해서 알아보자.

MDN 문서에서 이야기하기를 우리가 기존에 2d로 보였던 요소들이 3d요소로 보일 수 있는 원인은 모두 perspective(원금감) 속성 덕분이라고 한다.

원리는 간단했다. 부모요소에는 perspective 속성을 부여하고(관측자로부터 멀어지게 하거나 가깝게 하고) 자식요소 에게는 기존에 2d transform 속성을 부여해줌으로써 자식요소가 마치 공중에 떠있다거나 움직이는 것처럼 보여지게 하는 원리이다.

아래 그림을 보면 이해가 될 것이다.

위 그림의 Z축이 사용자가 정의한 perpective, 소실점 값이다.
소실점 반영이 500px라고 가정할 경우, 떨어진 관찰자 시점에서 요소가 150px 만큼 Z축을 따라 옮겨진다면(perpective : 500px - 150px) 앞으로 튀어나온 것과 같은 시각적인 효과가 나타나게 되는 것이다.

📚 CSS를 활용한 animation 최적화 기법

뭐 때문에 animation을 쓰는데 최적화를 신경써야 한다는 말인가?

animation은 한가지 단점이 존재한다. 바로 빈번하고 복잡한 애니메이션 사용될 때 오히려 웹 페이지의 성능을 떨어뜨릴 수 있다는 사실이다.

웹 페이지를 화려하게 만들도록 도와주는 animation이 오히려 그 성능을 악화시킨다니..분명 웹 개발자들에게는 중요한 사항이다.

그렇다면 왜 animation을 사용하면 웹 페이지의 성능이 떨어지는 걸까?

그 이유는 리플로우(reflow)리페인트(repaint)가 발생하기 때문이다.

Reflow란, 브라우저가 웹 페이지를 렌더링할 html 요소의 위치나 크기 등이 변경될 때 해당 요소와 요소를 포함한 상위, 하위 요소의 레이아웃을 다시 계산하고 렌더링하는 과정을 말하며 Repaint는 요소가 변경될 때 css 속성 등을 다시 렌더링하는 과정을 의미한다.

Repaint의 경우 Visiblity를 Dom Api을 통해 조절했을 때 자식 노드들까지 다 검색하기 때문에 성능 저하를 발생시킬 수도 있다고 한다.(100퍼센트 이해는 안되어도 딱 들었을 때 정말 불필요한 작업인 것 같다.)

그렇다면 어떻게 해야 Reflow / Repaint를 최대한 줄일 수 있을까?

이제 본격적으로 최적화 기법에 대해서 알아보자.

Refaint Reflow 최적화 기법 (= animation 최적화 기법)

  1. 플로우와 리페인트가 발생하는 코드들 최대한 줄이기.(완전히 안 쓰는 것은 말도 안되고 최대한 줄이기!)리플로우가 발생하는 속성
    아래는  리플로우(reflow)와 리페인트(repaint)가 발생하는 속성들이다.

    리페인트가 발생하는 속성들
    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 / width / height / padding / margin / display / border-width / border / top / position / font-size / float / text-align / overflow-y / font-weight / overflow / left / font-family / line-height / vertical-align / right / clear / white-space / bottom / min-height

  2. 3D transform 사용하기
    transform은 부모 요소의 영향을 받지 않으면서 독자적으로 요소의 위치 및 확대, 축소, 회전이 가능한 css 요소이다. 그렇기 때문에 transform을 사용하면 브라우저에서 GPU(그래픽 처리 장치)를 사용하며 이것은 CPU에 부담을 덜어줄 수 있기 때문에 성능을 저하하지 않게 된다. 또 transform 3d의 경우에는 x,y,z 축으로 3차원상에서 이동할 수 있기 때문에 자연스러운 움직임을 구현해낼 수 있다.
  1. 인라인 스타일을 사용하지 않는다.
    인라인 스타일은 HTML이 파싱될 때, 레이아웃에 영향을 미쳐 추가 리플로우를 발생시킨다. 또한 관심사 분리가 제대로 이루어지지 않으면 유지 보수가 힘들어 진다.
  2. animation이 부여된 요소는 position : fixed, absolute 사용하기
    애니메이션 효과를 줘야 하는 요소에 position 속성이 적용이 되지 않았다면 애니메이션 시작 시 position 속성 값을 fixed 또는 absolute로 변경하였다가 애니메이션 종료 후 다시 원복시켜서 렌더링을 최적화 할 수 있다.
    애니메이션 효과는 많은 reflow 비용을 발생시킨다. position 속성을 fixed 또는 absolute의 값으로 주어, 지정된 요를 전체 노드에서 분리시켜 해당 노드에서만 reflow가 발생하도록 제한시킬 수 있다.

  3. <table> 레이아웃은 피하기
    table은 점진적으로 렌더링 되지 않고, 모두 로드되고 테이블 너비가 계산된 후에 화면에 그려진다. 테이블 안의 컨텐츠의 값에 따라 테이블 너비가 계산 된다. 따라서 테이블 컨텐츠의 작은 변경만 있어도 테이블 너비가 다시 계산되고 테이블의 모든 노드들이 reflow가 발생한다. 이러한 이유로 table을 레이아웃 용도로 사용하는 일은 피해야 한다.