CSS 키 프레임 애니메이션 CPU 사용량이 높습니다. 이렇게해야합니까?


79

여러 요소에 다음 키 프레임 애니메이션을 사용합니다.

@keyframes redPulse {
    from { background-color: #bc330d; box-shadow: 0 0 9px #333; }
    50% { background-color: #e33100; box-shadow: 0 0 18px #e33100; }
    to { background-color: #bc330d; box-shadow: 0 0 9px #333; }
}
@-webkit-keyframes redPulse {
    from { background-color: #bc330d; box-shadow: 0 0 9px #333; }
    50% { background-color: #e33100; box-shadow: 0 0 18px #e33100; }
    to { background-color: #bc330d; box-shadow: 0 0 9px #333; }
}
.event_indicator {
    display: inline-block;
    background-color: red;
    width: 5px;
    margin-right: 5px;

    -webkit-animation-name: redPulse;
    -webkit-animation-duration: 1s;
    -webkit-animation-iteration-count: infinite;

    animation-name: redPulse;
    animation-duration: 1s;
    animation-iteration-count: infinite;
}

내 컴퓨터에서 Chrome과 Firefox 모두 CPU 사용량이 약 40 %입니다. 애니메이션의 현재 상태 (좋지만 지금은 사용할 수 없음)입니까? 아니면 마법 속성이 누락 되었습니까?

동일한 애니메이션으로 다음 샘플을 확인할 수 있습니다. http://jsfiddle.net/Nrp6Q/


1
높은 CPU 외에도 Chrome 작업 관리자를 기반으로하는 메모리 사용량이 계속 증가하는 것과 관련이있는 것 같습니다.
Kevin Bullaughey

@KevinBullaughey, 분명히 모든 개체에는 비용이 따릅니다. 시스템 RAM 및 / 또는 GPU에서 메모리를 차지하고 설명을 참조 하세요 . 애니메이션 자체는 비교적 비용이 많이 드는 작업입니다!
Farside

2
상자 그림자를 애니메이션하지 마십시오. 대신 box-shadow 속성을 가상 요소로 이동하고 불투명도 및 변형 속성에 애니메이션을 적용
Denis

@Denis move box-shadow property to pseudoelement and animate it's opacity and transform propertiesOP에 대한 질문이 꽤 오래 되었다는 것을 알고 있지만 예제 또는 참조를 제공 할 수 있습니까?
tonix

답변:


92

예, 페이지에 여러 개의 무한 루프 애니메이션이 있기 때문에 이것은 정상입니다. 따라서 CPU는 이러한 요소가 렌더링되는 동안 지속적으로 작업을 수행합니다. CPU 사용량을 크게 줄이는 "마법"속성이 있습니다.

transform: translateZ(0);

이렇게하면 요소가 자체 레이어로 합성되고 (브라우저가 3D 변환을 수행 할 것이라고 생각하도록 속임으로써) 브라우저는 대부분의 경우 GPU 가속을 활용하여 CPU의 부담을 줄여야합니다. 나를 위해 이것은 약 20 % (거의 절반)까지 줄였습니다.

이 기술에 대한 자세한 내용은 http://ariya.blogspot.com/2011/07/fluid-animation-with-accelerated.html을 참조하십시오.

또한 애니메이션에 키 프레임이 많을수록 더 많은 부담이됩니다. 중간 키 프레임을 잘라낸 상태로 애니메이션을 시도하면 CPU 사용량이 또 다른 상당한 (~ 10-12 %) 감소하는 것을 볼 수 있습니다.

마지막으로, 모든 속성이 동일하지는 않습니다. box-shadow는 브라우저가 배경색보다 매끄럽게 움직이는 것이 훨씬 어렵습니다. 모든 키 프레임은 그대로두고, translateZ (0) 트릭을 사용하여 box-shadow 속성을 삭제하면 CPU 사용량이 10-11 %에 불과했습니다.

이렇게 말하는 것이 고통 스럽지만, 무한 루프 애니메이션의 경우 애니메이션 .gif는 브라우저 애니메이션의 현재 상태에서 CSS3보다 훨씬 더 나은 성능을 발휘할 것입니다. 한동안 페이지.

2017 업데이트 :

여전히이 질문과 답변에 대한 방법을 찾는 사람들에게 , 당신은 설정 과 translate3d(0, 0, 0)동시에 동일한 이점을 제공합니다 . 데모에서 사용 하는 @Farside 의 주석을 무시하십시오. 그러나이 기술을 사용하면 여전히 상당한 차이가 있음을 알 수 있습니다.translateZ(0)translateX()translateY()translate3d(X, Y, Z)translate(X, Y)

이 질문 에 따르면 일부 사람들은 모든 브라우저, 특히 Chrome에서 transform: rotateZ(360deg).


3
아니요, 더 이상 차이가 없습니다 . Firefox 45.0.2에서 시도하고 Chrome 50.0.2661에서 시도했습니다. 가짜 변형 없이도 가능한 한 GPU를 적용하고 있다고 생각합니다 translateZ(0). 나에게 CSS 애니메이션은 사소한 정사각형의 간단한 애니메이션으로 CPU를 많이 가열하기 때문에 지금 사용하는 것은 나쁜 생각 인 것 같습니다 .
Farside 2016-04-26

1
귀하의 결과가 위에 적힌 내용과 일치 할 때 왜 반대 투표를합니까? 이 예제에서 무한 루프가 실행되고 있습니다. 제 CPU 사용량은 10-14 %입니다. translatez (0)을 사용하는 것과 동일한 translate3d를 사용했습니다. 제거하면 CPU 사용량이 증가합니다. 확실히 여전히 차이를 만듭니다.
skyline3000

4
@Farside는 완전히 잘못되었거나 잘못된 정보를 제공하므로 귀하의 댓글을 수정하거나 삭제하는 것을 고려하십시오. 귀하의 데모와 함께 및없이 애니메이션을 비교하지 않습니다 translateZ(0), 그것은 단지 보여줍니다 translate3d(x, y, z). 이를 just과 비교해 보면 translate(x, y)이 방법이 여전히 만드는 중요한 차이를 볼 수 있습니다.
skyline3000

1
감사합니다! CPU 부하를 170 % (!)에서 13 %로 줄입니다. 와.
Zack Katz

1
@ skyline3000 translateZ 메서드는 macOS에서 성능을 향상시키지 않는 것 같습니다. 다음은 내 예입니다. stackoverflow.com/questions/47296808/…
Winston

17

CPU의 부하를 줄일 수있는 가능한 방법 중 하나는 소위를 사용하는 null transform hack것입니다 . 이 방법은 종종 은색 총알 처럼 환영받습니다 . 대부분의 경우 Chrome, Opera 및 Safari와 같은 WebKit 및 Blink 브라우저에서 렌더링 성능을 크게 향상시킵니다.

"Null transform hack"(하드웨어 합성 모드) 사용

널 변환 해킹은 기본적으로 두 가지 작업을 수행합니다.

  1. 하드웨어 합성 모드를 켭니다 (플랫폼에서 지원된다고 가정).
  2. 자체 뒷면 이있는 새 레이어를 만듭니다.

브라우저를 "강제"하려면 다음 CSS 속성 중 하나를 요소에 추가하면됩니다.

transform: translateZ(0);

/* or its friend: */
transform: translate3d(0, 0, 0);

3D 변형으로 작업 할 때 성능을 향상시키기 위해 다음과 같은 속성도 갖는 것이 좋습니다 .

backface-visibility: hidden;
perspective: 1000;

"null transform hack"의주의 사항

많은 객체에 대해 CSS3에서 하드웨어 가속을 활성화하면 성능이 저하 될 수 있습니다! 분명히 각 null 3D 변환은 새 레이어를 만듭니다. 그러나 강제 해킹 레이어 생성이 페이지의 특정 성능 병목 현상에 대한 해결책이 아닐 수도 있습니다. 레이어 생성 기술은 페이지 속도를 높일 수 있지만 비용이 발생합니다. 시스템 RAM과 GPU에서 메모리를 차지합니다. 따라서 GPU가 잘 작동하더라도 많은 객체의 전송이 문제가 될 수 있으므로 GPU 가속을 사용하는 것이 그만한 가치가 없을 수 있습니다. W3C 의 인용 :

그러나 새 레이어에서 요소를 설정하는 것은 비교적 비용이 많이 드는 작업이므로 변환 애니메이션의 시작이 눈에 띄게 1 초 정도 지연 될 수 있습니다.

3D 가속을 사용할 때 많은 작은 항목을 이동하는 것보다 몇 개의 큰 개체를 이동하는 것이 성능이 더 높습니다. 따라서 그것들은 현명하게 사용되어야하며 하드웨어 가속 작업이 페이지의 성능에 실제로 도움이되는지 확인하고 성능 병목 현상이 페이지의 다른 작업으로 인해 발생하지 않는지 확인해야합니다.

또한 GPU는 복잡한 수학적 / 기하학적 계산을 수행하기 위해 특별히 설계되었으며 GPU에 대한 작업을 오프 로딩 하면 엄청난 전력 소비가 발생할 수 있습니다 . 분명히 하드웨어가 작동하면 대상 장치의 배터리도 작동합니다.

현대적인 방법 : will-change재산

진전은 한곳에 서 있지 않습니다 ... W3C는 will-changeCSS 속성을 도입 했습니다. 간단히 말해서이 will-change속성을 사용하면 요소에 적용 할 수있는 변경 사항의 종류를 미리 브라우저에 알릴 수 있으므로 필요하기 전에 적절한 최적화를 설정할 수 있습니다.

초안 에서 그들이 말하는 내용은 다음과 같습니다 .

will-change이있어 필요할 때 전에 UA가 시간이 적절한 최적화를 설정할 수 있도록이 사양에 정의 된 속성은, 저자가 앞서-의 시간 속성이 미래의 변화 가능성이 무엇을 선언 할 수 있습니다. 이렇게하면 실제 변경이 발생하면 페이지가 빠르게 업데이트됩니다.

를 사용 will-change하여 브라우저에 다가오는 변환에 대해 암시하는 것은 변환 될 것으로 예상되는 요소에이 규칙을 추가하는 것만 큼 간단 할 수 있습니다.

will-change: transform;

모바일 용으로 개발할 때 개발자는 모바일 웹 앱을 작성하는 동안 다양한 장치 제약 조건을 고려해야합니다. 브라우저는 점점 더 스마트 해지고 있으며, 때로는 가속을 겹치거나 해키 방식으로 동작을 강제하는 대신 결정을 플랫폼 자체에 맡기는 것이 좋습니다.


그것은에 상태 MDN 페이지 "너무 많은 요소에 의지-변경 사항을 적용하지 않는다." 및 "조금 사용하십시오." 내부적으로이 속성의 현재 브라우저 구현은 대부분 여전히 요소를 합성하는 것입니다. 이 기능은 비표준 일뿐만 아니라 (아직도 작업 초안 임) 분명 "실버 총알"접근 방식이 아닙니다. 또한 귀하의 답변은 실제로 OP의 CPU 사용량에 대해 설명하지 않으며 CPU 사용량 비교도 표시하지 않습니다.
skyline3000

2
@ skyline3000, 저는 장단점 및 경고를 작성했습니다. 좀 더주의 깊게 읽어보세요 will-change.-제 권장 사항은 아니지만 , 강제하는 대신 "브라우저에 다가오는 변환에 대해 암시" 하는보다 우아하고 현대적인 방법입니다 . "은총 알처럼 환영받는"- 당신이 말했듯 null transform hackwill-change재산이 아니라 소위에 속합니다 . 나는 당신의 다운 투표를
받아도 괜찮

4

CSS3로 일부 요소를 애니메이션 할 때 CPU 사용량이 높은 비슷한 경우가있었습니다. 전체 페이지에 사용 된 불투명도 및 그림자 속성을 사용하여 ~ 7 개 요소의 "왼쪽"속성에 애니메이션을 적용했습니다. 슬프게도 성능이 전혀 향상되지 않은 jQuery.animate로 전환하기로 결정했습니다. 페이지를 표시하는 동안 내 CPU (i7)는 여전히 ~ 9-15 % 였고, 몇 가지 트릭 (translateZ 등)도 실제로 성능을 향상시키지 못했습니다. 내 레이아웃이 엉망이되는 동안 (일부 절대 위치 요소가 포함되었습니다. !).

그런 다음이 멋진 확장 기능을 발견했습니다. http://playground.benbarnett.net/jquery-animate-enhanced/

나는 단순히 .js 파일을 참조하고 jQuery 전환에서 단일 변경을 수행하지 않았으며 내 CPU 사용량은 이제 동일한 페이지에서 1-2 %입니다.

내 추천 : CSS3 전환을 사용하여 CPU 문제에 직면 할 때 jQuery + animate-enhanced-plugin으로 전환하십시오.


1
대부분의 경우 많은 프로젝트에 jquery가 종속성으로 포함되어 있지 않으므로 추가 번들을 가져 오는 것은 잠재적으로 허용되지 않습니다.
Dimitris Filippou

3

CPU 대신 GPU를 사용하려는 다음 클래스 요소에서 이것을 사용할 수도 있습니다.

.no-cpu {
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
    -ms-transform: translateZ(0);
}

<element class="event_indicator no-cpu">animation...</element >

1
'will-changes'를 잊어 버렸고, 'no-cpu'는 매우 부정확하고 오해의 소지가 있기 때문에 'force-gpu'로 이름을 바꿔야합니다.

1

여기에보고 된 '펄싱'배경 애니메이션의 특정 사례에 대해 저는 css + js 솔루션을 생각해 냈습니다.

제 경우에는 배경 애니메이션이 배경색이 아닌 배경 위치 속성에 있었지만 원리는 동일합니다.

예, 특정 배경을 가진 블록이 있다고 가정 해 보겠습니다.

<div class="nice-block">...</div>

스타일 지정 : (scss)

.nice-block {
  background-color: red;
  //or it can be: background: linear-gradient(45deg, #red, #white, #red);
  //and:          background-size: 600% 600%;

  //the transform and will-change properties
  //are here to only enable GPU
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  will-change: transform;

  transition: background-color 5s ease;
  //if you want to add a pulsing effect 
  //to a gradient, see the following two lines:
  // background-position: 0% 50%!important;
  // transition: background-position 5s ease;

  &.animated {
    background-color: white;
    //and in case of gradient animation:
    // background-position: 100% 50%!important;
  }
}

이제 JavaScript를 사용하여 블록에 'animated'클래스를 추가하여 효과를 만들 차례입니다.

var bgAnimateTimer;
function animateBg () {
  clearTimeout(bgAnimateTimer);
  bgAnimateTimer = setTimeout(function () {
    clearTimeout(bgAnimateTimer);
    bgAnimateTimer = setTimeout(function () {

      document.querySelector('.nice-block').classList.toggle('animated');

      //jQuery alternative is:
      // $('.nice-block').toggleClass('animated');

      animateBg ();
    }, 5000); //5 seconds for the animation effect
  }, 2500); //2.5 seconds between each animation
}

animateBg ();

이것은 제 경우의 성능을 ~ 15 배 향상 시켰습니다.

(i) 5 초와 다른 값을 원하는 경우 css 및 js에서 전환 및 시간 초과에 대한 초를 올바르게 계산합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.