고성능 CSS 애니메이션의 예

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

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

마법사 로드 애니메이션

CodePen에서 뷰어 로드 애니메이션 보기

이 로드 애니메이션은 CSS로 완전히 빌드됩니다. 이미지와 모든 애니메이션이 CSS 및 HTML로 만들어졌으며 이미지나 JavaScript는 없습니다. 생성 방법과 실적을 파악하려면 Chrome DevTools를 사용하세요.

Chrome DevTools로 애니메이션 검사

애니메이션이 실행되는 동안 Chrome DevTools에서 성능 탭을 열고 애니메이션을 몇 초 동안 녹화합니다. 이 애니메이션을 실행할 때 브라우저에서 레이아웃 또는 페인트 작업을 실행하지 않는다는 내용이 요약에 표시됩니다.

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

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

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

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

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에서 깜박이는 원 보기

이 유형의 애니메이션은 페이지의 특정 내용에 대한 관심을 유도하는 데 사용되기도 합니다. 애니메이션을 이해하려면 Firefox DevTools를 사용하면 됩니다.

Firefox DevTools로 애니메이션 검사

애니메이션이 실행되는 동안 Firefox DevTools에서 성능 탭을 열고 애니메이션을 몇 초 동안 녹화합니다. 기록을 중지합니다. 그러면 폭포에 ReCalculate Style에 관한 항목이 표시되지 않습니다. 이제 이 애니메이션이 스타일 재계산을 일으키지 않으므로 레이아웃 및 페인트 작업도 발생하지 않는다는 것을 알 수 있습니다.

Firefox 폭포식 구조의 애니메이션 세부정보
Firefox DevTools 폭포식 차트

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 요소는 transform: scaleopacity에 애니메이션을 적용하는 pulse-ring라는 애니메이션을 사용하여 흰색 원의 외부로 확장되는 불투명한 링을 만듭니다.

.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에서 애니메이션 패널을 선택하는 것입니다. 그러면 사용 중인 애니메이션과 애니메이션이 적용되는 속성의 시각화가 표시됩니다.

::before 의사 요소를 선택하면 애니메이션이 적용되는 속성을 확인할 수 있습니다.

흰색 원 자체는 ::after 의사 요소를 사용하여 생성되고 애니메이션됩니다. 애니메이션 pulse-dottransform: 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에서 순수 CSS 3D 구체 보기

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

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);
  }
}

점은 planespoke 요소 내에 중첩되어 있으며 변환을 사용하여 크기를 조정하고 변환하는 애니메이션을 사용합니다. 이렇게 하면 깜빡이는 효과가 생깁니다.

점이 구체와 함께 회전하고 깜박입니다.
.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를 열고 실행 중에 Performance를 기록하여 애니메이션의 성능을 확인할 수 있습니다. 초기 로드 후에는 애니메이션이 레이아웃 또는 페인트를 트리거하지 않고 원활하게 실행됩니다.

결론

이러한 예시를 통해 성능이 우수한 메서드를 사용하여 몇 가지 속성에 애니메이션을 적용하여 매우 멋진 애니메이션을 만들 수 있는 방법을 확인할 수 있습니다. 기본적으로 애니메이션 가이드에 설명된 성능 기준에 맞는 메서드를 설정하면 페이지 속도 저하에 관한 우려를 줄이고 원하는 효과를 내는 데 시간을 할애할 수 있습니다.