방망이 깎는 코모

애니메이션을 최적화 하는 방법 본문

개념정리

애니메이션을 최적화 하는 방법

코모@kosmosticlay 2023. 12. 27. 04:48

애니메이션 최적화의 필요성

사용자 경험(UX) 향상을 위해 웹 페이지에 사용되는 애니메이션들은 로딩 시간이 짧고, 끊김이나 지연등의 방해 현상 없이 원활하게 동작해야 한다. 다만 일부 CSS 속성들은 CPU 자원을 많이 사용하는 리플로우(reflow)나 리페인트(repaint) 현상을 발생시킴으로써 전체 성능을 저하시킨다. 

DEV Community, https://dev.to/gopal1996/understanding-reflow-and-repaint-in-the-browser-1jbg

리플로우(reflow)
레이아웃 계산을 다시 하는 것을 말하며, 노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생한 경우에 한하여 실행된다.¹
리페인트(repaint)
재결합된 렌더 트리를 기반으로 다시 페인트하는 것을 의미한다.²

 

리플로우/리페인트를 발생시키는 대표 속성들은 다음과 같다. 이러한 속성들의 변경을 가능한 줄임으로써 웹 페이지의 반응성 저하를 줄일 수 있다.

 

✅ 리플로우가 발생하는 대표 속성

width height padding margin position top
bottom left right border border-width clear
display float font-family font-size font-weight line-height
min-height overflow text-align vertical-align white-space ...

 

리페인트가 발생하는 대표 속성

background background-image background-position background-repeat background-size border-radius
border-style box-shadow color line-style outline ouline-color
outline-style outline-width text-decoration visibility ...  

 

// 요소의 속성을 직접적으로 별도 설정시 두 번의 리플로우를 유발
var left = 10,
    top = 10;
el.style.left = left + "px";
el.style.top  = top  + "px";

// 요소에 클래스 이름을 추가함으로써 단일 리플로우/리페인트 발생
el.className += " theclassname";

// cssText를 사용하여 여러 스타일 속성을 한 번에 설정함으로써 단일 리플로우/리페인트 발생
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";

다양한 애니메이션 최적화 방법

  • 레이아웃 변경이 필요하다면 해당 변경이 필요한 요소를 미리 숨겨두고 변경 한 후, 다시 표시 되도록 설정한다.
  • DOM요소를 문서 흐름에서 일시적으로 제거한 후, 변경한 다음 다시 삽입하는 방법을 사용한다.
  • 여러 스타일 변경을 한 번에 적용하기 위해 요소의 클래스를 조작한다. (el.className 속성)
  • JS를 통해 스타일 변화가 필요하면, 가급적 한 번에 처리한다.

will-change 속성

개념 및 사용 방법

will-change 속성은 CSS에서 웹 페이지의 성능 최적화를 위해 사용된다. 브라우저에게 특정 요소에서 애니메이션 또는 스타일 변화가 예상되므로, 해당 요소에 대한 최적화를 미리 준비하라는 '신호'로써 사용된다. 이를 통해 브라우저는 해당 요소에 GPU 가속을 사용할 수 있도록 준비한다고 한다. GPU 가속을 사용한다는 의미는, 특정 작업을 처리하는데 CPU대신 GPU(Graphics Processing Unit)을 사용한다는 것을 의미하며, GPU는 본래 그래픽 처리를 위해 설계되었지만 그 구조가 병렬처리에 매우 적합하기 때문에 특히 그래픽과 관련된 작업에서 효율적이다는 특징이 있다.

 

will-change 속성에 대한 문서를 읽어보면 '레이어(Layer)' 개념과 관련이 있는 것을 알 수 있다. 브라우저는 웹 페이지를 렌더링할 때, 다양한 요소들을 레이어로 구분하여 처리한다. will-change 속성을 적용함으로써 한 요소의 변경이 전체 페이지의 재렌더링을 유발하지 않고, 자신만의 독립적인 레이어를 처리를 통해 해당 요소만 다시 리페인트될 수 있으므로 성능과 접근성을 높일 수 있게 된다.

.element {
  will-change: transform, opacity;
}

 

 

✅ will-change와 사용하기 적합한 속성 :

transform opacity filter scroll-position contents ...

 

예를 들어, will-change 속성에 contents 값을 사용하는 경우는 주로 요소의 텍스트 내용이나 이미지와 같은 자식 요소들이 자주 변경될 때 사용된다. 브라우저에게 해당 요소의 컨텐츠를 캐시(cache)하지 말라는 신호를 보내는 데, 이는 데이터나 정보를 캐시(임시 메모리 영역)에 저장하지 않도록 하는 것을 의미한다. 즉, 캐시 방지를 통해 사용자가 오래된 정보에 노출되지 않고 항상 최신 정보를 볼 수 있도록 보장하는 기능을 하는 것이다. 

 

✅ will-change와 사용을 지양해야 하는 속성

width height top bottom right left
color background-color font-size font-decoration border-style ...

사용시 주의사항

  • 과도한 사용 자제 : 불필요하게 많은 요소에 will-change 속성을 사용하면, 많은 리소스를 최적화에 사용하게 되어 오히려 전반적인 성능에 부정적인 영향을 미칠 수 있다.
  • 애니메이션/스타일 변화가 일어나기 직전에만 사용 후, 반드시 제거 : will-change의 경우 최적화가 길게 유지되므로 해당 요소의 변화가 종료되면 반드시 해당 속성을 삭제해서 사용하고 있던 자원을 회수해야 한다.
  • 브라우저 종류에 따른 호환성 체크 : 모든 브라우저가 will-change 속성을 동일하게 처리하지 않으므로 브라우저 간의 렌더링 방식 차이와 호환성을 함께 고려해야 한다.

 

 


마치며

다른 개발자분의 코드에서 will-change라는 속성을 보았던 기억이 있어서 해당 속성을 이용/최적화 방법은 별도로 살펴보았다. 개인적으로도 역동적이고 상호작용하는 UI/UX들에 대한 관심이 많기 때문에 애니메이션 최적화에 대해 정리해볼 수 있어서 좋은 경험이었다. 다음 프로젝트를 진행할 때는 때 해당 속성을 적용하고, 개발자도구의 Performance/Event Log 페이지에서 해당 기능의 성능을 비교하고자 한다.

 


참고 문헌

1. DEV Community, Understanding Reflow and Repaint in the browser : https://dev.to/gopal1996/understanding-reflow-and-repaint-in-the-browser-1jbg

2. 모던자바스크립트, 이웅모, 38.7 리플로우와 리페인트(p672,673)¹²

3. 박스 여우, 브라우저 렌더링 성능 최적화 - Repaint가 일어나지 않는 CSS 속성 : https://boxfoxs.tistory.com/409

4. WIT블로그, CSS 애니메이션 성능 개선 방법 (reflow 최소화, will-change 사용) : https://wit.nts-corp.com/2017/06/05/4571

5. W3C, CSS Will Change Module Level 1 : https://www.w3.org/TR/css-will-change/

6. LogRocket - Frontend Analytics, When and how to use CSS will-change :  https://blog.logrocket.com/when-how-use-css-will-change/

Comments