본문 바로가기
개발/CSS

애니메이션 최적화 : transform, opacity

by 안뇽! 2023. 5. 19.
반응형

애니메이션 최적화 : transform, opacity

 transform은 요소에 회전,크기조정,기울기,이동효과를 부여한다. 이는 CPU가 아닌 GPU를 사용하여 렌더링되므로 애니메이션에 이 속성을 사용하면 성능이 향상될 수 있다. 

 

 opacity는 요소의 투명도를 설정한다. 이 속성도 GPU에서 렌더링되므로 애니메이션에서 이 속성을 사용하면 성능이 향상된다.

리플로우 리페인트

애니메이션 최적화를 논하기 전에 먼저 브라우저 렌더링 과정에 대한 이해가 필요하다. 이 내용 정도면 충분하다.

 

처음 화면이 모두 그려진 후에, JS로 인해 화면 내 어떤 Element의 width, height가 변경되면 브라우저는 해당 Element의 width,height를 다시 계산하여 변경된 사이즈로 화면을 그린다. 이를 리플로우라고 한다.

 

반면 배경색이 바뀌는 경우에는 Element의 크기가 바뀌진 않기 때문에 레이아웃 단계를 건너 뛰고 화면을 다시 그린다. 이를 리페인트라고 한다.

 

리플로우,리페인트 모두 DOM,CSSOM 생성 -> 렌더트리 -> 레이아웃(or 생략) -> 페인트 -> 렌더링 과정을 다시 거치는 것이기 때문에 리소스를 꽤 잡아먹는다.

리플로우, 리페인트를 피하는 방법

정리하면, Element의 CSS가 변경되면 리플로우나 리페인트 과정을 거치는데 이는 브라우저 리소스를 많이 잡아먹고, 애니메이션이 버벅이는 것을 유발할 수 있다.

 

다행히 리플로우, 리페인트를 피하는 방법이 있다. 바로 transfrom, opacity와 같은 속성을 이용하는 것이다.

 

위 속성들은 해당 Element를 별도의 레이어로 분리하고 작업을 GPU에 위임함으로써 레이아웃 단계와 페인트 단계를 건너 뛸 수 있다.

 

따라서 리플로우, 리페인트를 일으키는 width, height, color 등의 속성이 아닌 transform, opacity를 이용한 애니메이션 성능이 더 좋을 수 밖에 없다.

 

transform: translate() 는 처음부터 레이어를 분리하지 않고 변화가 일어나는 순간에 레이어를 분리한다.
transform: translate3d() 또는 scale3d()와 같은 3d 속성들, 또는 will-change 속성은 처음부터 레이어를 분리해두기 때문에 변화에 더 빠르게 대처할 수 있다.

다만 분리된 레이어가 너무 많아지면 그만큼 메모리를 많이 사용하기에 주의해야 함.

예시

// width를 통해 너비를 변경하는 애니메이션은 리플로우를 유발한다.

const BarGraph = styled.div`
    ...
    width: ${({width}) => width}%;
    transition: width 1.5s ease;
    ...
`
// width가 아닌 transform을 통해 너비를 변경하는 애니메이션은 해당 Element의 레이어를 분리하기 때문에
// 해당 Element의 레이어를 분리하기 때문에 리페인트를 유발하지 않는다.

const BarGraph = styled.div`
  ..
  width: 100%;
  transform: scaleX(${({ width }) => width / 100});
  transform-origin: center left;
  transition: transform 1.5s ease;
  ...
`;

 

애니메이션 최적화는 사용자 경험을 향상시키는 중요한 요소다. 따라서 효율적인 애니메이션을 만들기 위해 transform과 opacity 속성을 적극 활용하는 것이 중요하다.

반응형