CSS animation 버벅임 현상

웹 페이지를 볼 때 움직이는 요소가 버벅거리고, 브라우저의 동작이 느려지는 경우가 있다. 이러한 현상을 해결하기 위한 방법들을 정리해보자.

Reflow 와 Repaint 를 줄여라?

Reflow

Reflow란 렌더링 엔진에서 요소를 배치하는 과정을 말한다. 렌더링 엔진에 의해 브라우저가 렌더링 될 때 DOM트리와 스타일 규칙을 합쳐 렌터 트리를 만들고 Reflow를 통해 각각의 요소들의 레이아웃을 위치시킨다.

Repaint

Repaint 는 렌터 트리가 탐색되고 paint메서드가 호출되어 UI 기반의 구성요소를 사용해 그리는 과정이다.

위의 두 과정을 줄인다면 CSS성능을 조금 더 최적화할 수 있다고 한다. Reflow와 Repaint가 어떤 상황에 일어나는지 스타일 적용 과정을 보고 확인해보자.

스타일 적용 순서

1. Style : 브라우저가 객체에 적용할 스타일의 값을 계산 및 재계산

2. Layout : 브라우저가 객체의 모양과 위치 생성

  • width , height , padding, margin

3. Paint : 브라우저가 객체 영역의 픽셀을 채움

  • color , background, background-image, box-shadow

4. Composite : 브라우저 레이어순으로 객체를 화면에 그림

  • opacity, transform , rotate, scale

위의 순서에 따라 Layout 속성을 변경하면 paint composite 순서를 거치기 때문에 성능이 저하되고 이를 Reflow라고 한다. paint 속성만을 변경한다면 composite 순서를 거치고 성능 저하가 일어나며 이를 Repaint 라고 한다.

composite 속성만 변경한다면 최대한 적은 순서를 거칠 수 있으므로 최대 성능을 위한다면 composite 속성만 변경하는걸 권장한다.

Reflow,Repaint 최소화 방법

리플로우와 리페인트는 완전히 피할수는 없어 보인다. 하지만 최적화가 가능하다면 최대한 방법을 알고 줄이는게 현명하다.

무엇이 Reflow를 유발시키는가?

  • 윈도우 리사이징
  • 폰트의 변화
  • 스타일 추가 또는 제거
  • 내용 변화 (인풋 박스에 텍스트 입력 등..)
  • :hover 와 같은 css Pseudo class
  • 클래스 Attribute의 동적 변화
  • JS를 통한 DOM 동적 변화
  • 엘리먼트에 대한 offsetWidth / offsetHeight (화면에서 보여지는 좌표) 계산시
  • 스타일 Attribute 동적 변화

Reflow를 피하거나 영향을 최소화 하는 방법

  • 클래스 변화에 따른 스타일 변화를 원할 경우, 최대한 DOM 구조 상 끝단에 위치한 노드에 주기
  • 인라인 스타일을 최대한 배제하기
  • 애니메이션이 들어간 엘리먼트는 가급적 position:fixed 또는 position:absolute
  • 퀄리티와 퍼포먼스 사이에서 타협
  • 테이블 레이아웃을 피하기
  • IE의 경우 CSS에서의 JS표현식을 피하기
  • JS를 통해 스타일 변화를 주어야 할 경우 가급적 한번에 처리하기
  • CSS Rules 는 필요한 만큼만 정리
  • position:relative 사용시 주의하기

참고 문서 링크

Transform:translate3d?

애니메이션을 만들 때 Reflow를 유발하는 top,left 를 조절하는 대신 Composite 단계만 거치는 transform 속성을 이용해 translate로 애니메이션을 구현할 수 있다.

이때 translate3d ,translateZ, rotate3d, scale3d 옵션 등을 활용하면 GPU를 사용해 하드웨어 가속을 하게 된다. translate()보다 더 좋은 성능을 원한다면 3d 옵션을 활용해 보는것을 추천한다.

profile
프론트엔드 개발자가 되겠습니다🔥

1개의 댓글

comment-user-thumbnail
2023년 4월 2일

안녕하세요, 제로베이스 프론트엔드스쿨 멘토입니다. 작성해주신 글 잘 읽었고, 앞으로의 더 나은 블로깅을 응원하는 마음에서 작은 의견을 남기고 갑니다 :)

  • 전체적으로 잘 이해하고 정리해주셨습니다. 글 전체적으로 본인의 어투로 이해한 내용을 정리해주시고, 본인의 생각이 틈틈히 들어가있어서 좋았습니다.
  • minor) 현재 제목이 'CSS animation 최적화'인데요, 본문의 내용을 고려하여 조금 더 구체화해줘도 좋을 것 같습니다. 예) CSS animation 최적화 - Reflow와 Repaint
  • Reflow, Repaint 최소화 방법들에 대해 여러가지를 요약하여 개략적으로 적어주셨는데요, 조금만 더 디테일하게 내용을 적어줘도 좋을 것 같습니다. 이 내용을 정말 잘 이해했는지?를 좀 더 표현할 수 있으면 좋을 것 같다는 생각이 들어서요..! 예를 들어, 맨 마지막에 'position:relative 사용시 주의하기'라고 적어주셨는데, 왜 relative를 사용하면 안좋고, absolute를 사용하면 좋은지?라고 누군가 물어본다면, 다른 요소에 영향을 끼치지 않고, 페이지 전체가 아닌 해당 요소만 reflow가 발생하도록 하는 것이 좋기 때문이라고 대답할 수 있는지를 스스로 점검해보시고, 이해한 내용들을 조금씩 구체화해서 적어준다면 좋을 것 같습니다.
  • minor) 샘플 코드 등을 통해 이러한 이론들을 바탕으로, 직접 코드를 작성해본 경험이 드러난다면 더욱 좋을 것 같습니다.

감사합니다!

답글 달기