고성능 CSS 애니메이션을 만드는 방법

이 가이드에서는 고성능 CSS 애니메이션을 만드는 방법을 설명합니다.

이러한 권장사항의 이론적 배경을 알아보려면 일부 애니메이션이 느린 이유는 무엇인가요?를 참고하세요.

브라우저 호환성

이 가이드에서 권장하는 모든 CSS 속성은 교차 브라우저 지원이 우수합니다.

transform

Browser Support

  • Chrome: 36.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

opacity

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 2.

Source

will-change

Browser Support

  • Chrome: 36.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 9.1.

Source

요소 이동

요소를 이동하려면 transform 속성의 translate 또는 rotation 키워드 값을 사용합니다.

예를 들어 항목을 뷰로 슬라이드하려면 translate를 사용합니다.

.animate {
  animation: slide-in 0.7s both;
}

@keyframes slide-in {
  0% {
    transform: translateY(-1000px);
  }
  100% {
    transform: translateY(0);
  }
}

rotate를 사용하여 요소를 회전합니다. 다음 예에서는 요소를 360도 회전합니다.

.animate {
  animation: rotate 0.7s ease-in-out both;
}

@keyframes rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

요소 크기 조정

요소의 크기를 조정하려면 transform 속성의 scale 키워드 값을 사용합니다.

.animate {
  animation: scale 1.5s both;
}

@keyframes scale {
  50% {
    transform: scale(0.5);
  }
  100% {
    transform: scale(1);
  }
}

요소의 공개 상태 변경

요소를 표시하거나 숨기려면 opacity을 사용합니다.

.animate {
  animation: opacity 2.5s both;
}

@keyframes opacity {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

레이아웃 또는 페인트를 트리거하는 속성 피하기

애니메이션에 CSS 속성 (transformopacity 제외)을 사용하기 전에 속성이 렌더링 파이프라인에 미치는 영향을 확인합니다. 꼭 필요한 경우가 아니라면 레이아웃이나 페인트를 트리거하는 속성을 사용하지 마세요.

레이어 강제 생성

일부 애니메이션이 느린 이유는 무엇인가요?에서 설명한 대로 새 레이어에 요소를 배치하면 브라우저가 나머지 레이아웃을 다시 칠할 필요 없이 요소를 다시 칠할 수 있습니다.

브라우저는 일반적으로 새 레이어에 배치할 항목을 적절하게 결정할 수 있지만 will-change 속성을 사용하여 레이어 생성을 수동으로 강제할 수 있습니다. 이름에서 알 수 있듯이 이 속성은 브라우저에 이 요소가 어떤 방식으로든 변경될 예정이라고 알립니다.

CSS에서 will-change를 모든 선택기에 적용할 수 있습니다.

body > .sidebar {
  will-change: transform;
}

그러나 사양에 따르면 항상 변경될 요소에만 이를 추가해야 합니다. 예를 들어 사용자가 슬라이드하여 넣고 뺄 수 있는 사이드바에 사용할 수 있습니다. 요소가 자주 변경되지 않는 경우 변경될 가능성이 있을 때 JavaScript를 사용하여 will-change를 적용합니다. 브라우저가 필요한 최적화를 실행할 수 있도록 충분한 시간을 주고 변경이 중지되면 속성을 삭제합니다.

will-change를 지원하지 않는 브라우저에서 레이어 생성을 강제하려면 transform: translateZ(0)를 설정하면 됩니다.

느리거나 글리치가 있는 애니메이션 디버그

Chrome DevTools 및 Firefox DevTools를 사용하면 애니메이션이 느려지거나 글리치가 발생하는 이유를 파악할 수 있습니다.

애니메이션이 레이아웃을 트리거하는지 확인

transform 이외의 항목을 사용하여 요소를 이동하는 애니메이션은 느릴 수 있습니다. 다음 예에서는 transform를 사용하는 애니메이션을 topleft를 사용하는 애니메이션과 비교합니다.

금지사항
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     top: calc(90vh - 160px);
     left: calc(90vw - 200px);
  }
}
권장사항
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     transform: translate(calc(90vw - 200px), calc(90vh - 160px));
  }
}

다음 두 가지 예에서 이를 테스트하고 DevTools를 사용하여 성능을 살펴볼 수 있습니다.

Chrome DevTools

  1. 실적 패널을 엽니다.
  2. 애니메이션이 실행되는 동안 런타임 성능을 기록합니다.
  3. 요약 탭을 검사합니다.

요약 탭에 렌더링의 값이 0이 아닌 경우 애니메이션으로 인해 브라우저에서 레이아웃 작업을 실행하고 있을 수 있습니다.