고성능 CSS 애니메이션의 예

이 게시물에서는 CodePen에서 찾을 수 있는 인기 애니메이션이 어떻게 만들어졌는지 알아봅니다. 이러한 애니메이션은 모두 이 섹션의 다른 도움말에서 설명하는 성능이 우수한 기법을 사용합니다.

이러한 권장사항의 이론적 배경은 일부 애니메이션이 느린 이유를 참고하고, 실용적인 팁은 애니메이션 가이드를 참고하세요.

마법사 로드 애니메이션

CodePen에서 마법사 로드 애니메이션 보기

이 로딩 애니메이션은 전적으로 CSS로 빌드되었습니다. 이미지와 모든 애니메이션은 CSS와 HTML로 생성되었으며, 이미지나 JavaScript는 사용되지 않았습니다. Chrome DevTools를 사용하면 이 페이지가 어떻게 생성되었고 얼마나 잘 작동하는지 파악할 수 있습니다.

Chrome DevTools로 애니메이션 검사

애니메이션이 실행 중인 상태에서 Chrome DevTools의 Performance 탭을 열고 애니메이션을 몇 초 동안 기록합니다. 요약에서 이 애니메이션을 실행할 때 브라우저가 레이아웃 또는 페인트 작업을 실행하지 않는 것을 확인할 수 있습니다.

DevTools의 요약
마법사 애니메이션을 프로파일링한 후의 요약

레이아웃과 페인트를 일으키지 않고 이 애니메이션을 구현하는 방법을 알아보려면 Chrome DevTools에서 움직이는 요소를 검사하세요. 애니메이션 패널을 사용하여 다양한 애니메이션 요소를 찾을 수 있으며, 요소를 클릭하면 DOM에서 강조 표시됩니다.

애니메이션의 다양한 부분을 보여주는 애니메이션 패널
Chrome DevTools Animation 패널에서 항목 보기 및 선택

예를 들어 삼각형을 선택하고 요소의 상자가 공중으로 이동하고 회전한 다음 시작 위치로 돌아가는 동안 어떻게 변환되는지 확인합니다.

Chrome DevTools에서 삼각형의 경로를 추적하는 방법을 보여주는 동영상

요소가 선택된 상태에서 스타일 패널을 확인합니다. 여기에서 삼각형 모양을 그리는 CSS와 사용 중인 애니메이션을 확인할 수 있습니다.

작동 방식

삼각형은 ::after 가상 요소를 사용하여 생성된 콘텐츠를 추가하고 테두리를 사용하여 도형을 만들어 생성됩니다.

.triangle {
    position: absolute;
    bottom: -62px;
    left: -10px;
    width: 110px;
    height: 110px;
    border-radius: 50%;
}

.triangle::after {
    content: "";
    position: absolute;
    top: 0;
    right: -10px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 28px 48px 28px;
    border-color: transparent transparent #89beb3 transparent;
}

애니메이션은 다음 CSS 줄을 사용하여 추가됩니다.

animation: path_triangle 10s ease-in-out infinite;

Chrome DevTools에서 스타일 패널을 아래로 스크롤하면 키프레임을 찾을 수 있습니다. 여기에서 transform를 사용하여 요소의 위치를 변경하고 회전하여 애니메이션이 생성되는 것을 확인할 수 있습니다. transform 속성은 애니메이션 가이드에 설명된 속성 중 하나로, 브라우저에서 레이아웃 또는 페인트 작업 (느린 애니메이션의 주요 원인)을 실행하지 않습니다.

@keyframes path_triangle {
  0% {
    transform: translateY(0);
  }
  10% {
    transform: translateY(-172px) translatex(10px) rotate(-10deg);
  }
  55% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  58% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  63% {
    transform: rotate(-360deg);
  }
}

이 애니메이션의 각 움직이는 부분은 유사한 기법을 사용합니다. 그 결과 복잡한 애니메이션이 원활하게 실행됩니다.

깜빡이는 원

CodePen에서 Pulsating Circle 보기

이러한 유형의 애니메이션은 페이지의 특정 요소에 주의를 끌기 위해 사용되기도 합니다. 애니메이션을 이해하려면 Firefox DevTools를 사용하면 됩니다.

Firefox DevTools로 애니메이션 검사

애니메이션이 실행 중인 상태에서 Firefox DevTools의 Performance 탭을 열고 애니메이션을 몇 초 동안 기록합니다. 녹화를 중지하면 Waterfall에 Recalculate Style 항목이 표시되지 않습니다. 이제 이 애니메이션이 스타일 재계산을 유발하지 않으므로 레이아웃 및 페인트 작업도 유발하지 않는다는 것을 알 수 있습니다.

Firefox Waterfall의 애니메이션 세부정보
Firefox DevTools Waterfall

Firefox DevTools에서 원을 검사하여 이 애니메이션이 어떻게 작동하는지 확인합니다. 클래스가 pulsating-circle인 <div>는 원의 위치를 표시하지만 원 자체를 그리지는 않습니다.

.pulsating-circle {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
    width: 30px;
    height: 30px;
}

표시되는 원과 애니메이션은 ::before 및 ::after 유사 요소를 사용하여 구현됩니다.

::before 요소는 pulse-ring이라는 애니메이션을 사용하여 흰색 원 바깥쪽으로 확장되는 불투명한 고리를 만듭니다. 이 애니메이션은 transform: scale 및 opacity에 애니메이션을 적용합니다.

.pulsating-circle::before {
    content: '';
    position: relative;
    display: block;
    width: 300%;
    height: 300%;
    box-sizing: border-box;
    margin-left: -100%;
    margin-top: -100%;
    border-radius: 45px;
    background-color: #01a4e9;
    animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

@keyframes pulse-ring {
  0% {
    transform: scale(0.33);
  }
  80%, 100% {
    opacity: 0;
  }
}

애니메이션이 적용되는 속성을 확인하는 또 다른 방법은 Firefox DevTools에서 Animations 패널을 선택하는 것입니다. 그러면 사용 중인 애니메이션과 애니메이션이 적용되는 속성이 시각화되어 표시됩니다.

::before 가상 요소를 선택하면 어떤 속성이 애니메이션 처리되는지 확인할 수 있습니다.

흰색 원 자체는 ::after 가상 요소를 사용하여 생성되고 애니메이션 처리됩니다. 애니메이션 pulse-dot는 transform: scale를 사용하여 애니메이션 중에 점을 확대하고 축소합니다.

.pulsating-circle::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 15px;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
  animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}

@keyframes pulse-dot {
  0% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.8);
  }
}

이와 같은 애니메이션은 애플리케이션의 다양한 위치에서 사용할 수 있으며, 이러한 작은 요소가 앱의 전반적인 성능에 영향을 미치지 않는 것이 중요합니다.

순수 CSS 3D 구체

CodePen에서 Pure CSS 3D Sphere 보기

이 애니메이션은 매우 복잡해 보이지만, 이전 예시에서 이미 살펴본 기법을 사용합니다. 복잡성은 많은 수의 요소에 애니메이션을 적용하는 데서 비롯됩니다.

Chrome DevTools를 열고 클래스가 plane인 요소 중 하나를 선택합니다. 구는 회전하는 평면과 스포크로 구성됩니다.

평면이 회전하는 것처럼 보입니다.

이러한 평면과 스포크는 래퍼 <div> 내부에 있으며, transform: rotate3d를 사용하여 회전하는 요소입니다.

.sphere-wrapper {
  transform-style: preserve-3d;
  width: 300px;
  height: 300px;
  position: relative;
  animation: rotate3d 10s linear infinite;
}

@keyframes rotate3d {
  0% {
    transform: rotate3d(1, 1, 1, 0deg);
  }
  25% {
    transform: rotate3d(1, 1, 1, 90deg);
  }
  50% {
    transform: rotate3d(1, 1, 1, 180deg);
  }
  75% {
    transform: rotate3d(1, 1, 1, 270deg);
  }
  100% {
    transform: rotate3d(1, 1, 1, 360deg);
  }
}

점은 plane 및 spoke 요소 내에 중첩되어 있으며, 변환을 사용하여 크기를 조절하고 변환하는 애니메이션을 사용합니다. 이렇게 하면 펄스 효과가 생성됩니다.

점이 구체와 함께 회전하며 깜빡입니다.
.spoke-15 .dot,
.spoke-21 .dot {
  animation: pulsate 0.5s infinite 0.83333333s alternate both;
  background-color: #55ffee;
}

@-webkit-keyframes pulsate {
  0% {
    transform: rotateX(90deg) scale(0.3) translateZ(20px);
  }
  100% {
    transform: rotateX(90deg) scale(1) translateZ(0px);
  }
}

이 애니메이션을 만드는 작업은 타이밍을 맞추고 회전 및 펄스 효과를 만드는 것이었습니다. 애니메이션 자체는 매우 간단하며 성능이 우수한 메서드를 사용합니다.

Chrome DevTools를 열고 실행 중에 성능을 기록하여 이 애니메이션의 성능을 확인할 수 있습니다. 초기 로드 후 애니메이션은 레이아웃이나 페인트를 트리거하지 않으며 원활하게 실행됩니다.

결론

이러한 예시를 통해 성능이 우수한 메서드를 사용하여 몇 가지 속성에 애니메이션을 적용하면 매우 멋진 애니메이션을 만들 수 있다는 것을 알 수 있습니다. 애니메이션 가이드에 설명된 성능이 우수한 메서드를 기본값으로 사용하면 페이지 속도 저하에 대한 걱정을 줄이면서 원하는 효과를 만드는 데 시간을 할애할 수 있습니다.