Подтвердить что ты не робот

Использование ключевого кадра CSS Использование ЦП является высоким, должно ли это быть таким образом?

Я использую следующую анимацию ключевого кадра для нескольких элементов:

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

На моем компьютере я получаю около 40% использования процессора как в Chrome, так и в Firefox. Является ли это текущим состоянием анимации (красивым, но не пригодным для использования сейчас), или я пропустил какое-то волшебное свойство?

Вы можете проверить следующий пример с той же анимацией: http://jsfiddle.net/Nrp6Q/

4b9b3361

Ответ 1

Да, это нормально, потому что на странице есть несколько анимаций с бесконечной петлей. Поэтому ЦП постоянно выполняет работу, пока эти элементы визуализируются. Существует "волшебное" свойство, которое значительно сократит использование ЦП, а именно:

transform: translateZ(0);

Это объединит элементы в свои собственные слои (обманом браузера, думая, что он будет делать 3D-преобразования), и браузер должен в большинстве случаев использовать ускорение GPU, уменьшая нагрузку на процессор. Для меня это сократилось примерно на 20% (почти половина).

Чтобы узнать больше об этой технике, посмотрите: http://ariya.blogspot.com/2011/07/fluid-animation-with-accelerated.html

Кроме того, чем больше ключевых кадров у вас есть в анимации, тем больше налогов будет. Просто попробуйте анимацию с вырезанным средним ключевым фреймом, и вы увидите еще одно существенное (~ 10-12%) падение использования ЦП.

Наконец, не все свойства равны - для тени браузера гораздо труднее анимировать браузер, чем, скажем, цвет фона. Оставив все ключевые кадры нетронутыми, но потеряв свойство box-shadow, используя трюк translateZ (0), использование моего процессора зависело только на 10-11%.

Насколько мне больно это говорить, для анимаций с бесконечным циклом анимированный .gif будет работать намного, намного лучше, чем CSS3 в текущем состоянии анимации браузера, особенно если вы планируете, чтобы многие из них оставались отображаемые на странице в течение некоторого времени.

Обновление 2017:

Для тех, кто все еще находит свой путь к этому вопросу и ответам, translate3d(0, 0, 0) обеспечивает такое же преимущество, как translateZ(0), вы также устанавливаете одновременно translateX() и translateY(). Пожалуйста, проигнорируйте комментарий @Farside, поскольку он использует translate3d(X, Y, Z) в своей демонстрации, но не сравнивает его с translate(X, Y), который показывает, что использование этого метода все еще делает существенная разница.

Согласно этому вопросу, некоторые люди нашли лучшую производительность во всех браузерах, особенно в Chrome, с transform: rotateZ(360deg).

Ответ 2

Один из возможных способов уменьшить нагрузку на процессор - использовать так называемый null transform hack, который часто называют серебряной пулей. Во многих случаях это значительно улучшит производительность рендеринга в браузерах WebKit и Blink, таких как Chrome, Opera и Safari.

Использование "взлома нулевого преобразования" (режим аппаратного композитинга)

Хак с нулевым преобразованием в основном делает две вещи:

  1. Он включает режим аппаратного композитинга (при условии, что он поддерживается для платформы)
  2. Создает новый слой с собственной подложкой

Чтобы "заставить" браузер, просто добавьте одно из этих свойств CSS к элементу:

transform: translateZ(0);

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

При работе с 3D-преобразованиями также полезно иметь эти свойства для повышения производительности:

backface-visibility: hidden;
perspective: 1000;

Предостережения о "взломе нулевого преобразования"

Включение аппаратного ускорения в CSS3 для многих объектов может снизить производительность! По-видимому, каждое нулевое 3D-преобразование создает новый слой. Однако создание слоя принудительного взлома не всегда может быть решением некоторых узких мест производительности на странице. Методы создания слоев могут повысить скорость страницы, но они обходятся дорого: они занимают память в системной памяти и на графическом процессоре. Таким образом, даже если графический процессор делает хорошую работу, перенос многих объектов может стать проблемой, так как использование ускорения графического процессора может не стоить того. Цитата из W3C:

Однако установка элемента в новом слое является относительно дорогой операцией, которая может задержать начало анимации преобразования на заметную долю секунды.

Перемещение нескольких больших объектов имеет более высокую производительность, чем перемещение множества мелких предметов при использовании 3D-ускорения. Таким образом, они должны использоваться с умом, и вы должны убедиться, что аппаратное ускорение вашей работы действительно повысит производительность вашей страницы, и что узкое место в производительности не вызвано другой операцией на вашей странице.

Кроме того, графический процессор разработан специально для выполнения сложных математических/геометрических вычислений, а операции разгрузки на графический процессор могут привести к значительному потреблению энергии. Очевидно, что когда включается аппаратное обеспечение, то же касается и батареи целевого устройства.

Современный способ: свойство will-change

Прогресс не стоит на месте... W3C представил CSS-свойство will-change. Короче говоря, свойство will-change позволяет вам заранее сообщить браузеру, какие изменения вы можете внести в элемент, чтобы он мог настроить соответствующие оптимизации, прежде чем они понадобятся.

Вот что они говорят в черновике draft:

Свойство will-change, определенное в этой спецификации, позволяет автору заблаговременно объявлять, какие свойства могут измениться в будущем, поэтому UA может настроить соответствующие оптимизации за некоторое время до того, как они потребуются. Таким образом, когда происходит реальное изменение, страница обновляется быстро.

Используя will-change, подсказка браузеру о предстоящем преобразовании может быть столь же простой, как добавление этого правила к элементу, который вы ожидаете преобразовать:

will-change: transform;

При разработке для мобильных устройств разработчики вынуждены принимать во внимание широкий спектр ограничений устройств при написании мобильных веб-приложений. Браузеры становятся умнее, и иногда лучше оставить решение за самой платформой, вместо того, чтобы перекрывать ускорение и навязывать поведение хакерским способом.

Ответ 3

У меня был аналогичный случай использования большого количества процессоров при анимации некоторых элементов с помощью CSS3. Я анимировал "left" -property из 7 элементов, с некоторыми свойствами opacity и shadow, которые использовались на моей странице. Я решил переключиться на jQuery.animate, что, к сожалению, не улучшило производительность вообще. Мой процессор (i7) все еще находился на уровне ~ 9-15% при отображении страницы, несколько трюков (translateZ и т.д.) На самом деле не улучшали производительность - при том, что мой макет перепутался (были задействованы некоторые элементы с абсолютным позиционированием, ouch!).

Затем я наткнулся на это замечательное расширение: http://playground.benbarnett.net/jquery-animate-enhanced/

Я просто ссылался на .js файл, не делал ни одного изменения в переходах jQuery, а использование моего процессора теперь составляет 1-2% на той же странице.

Моя рекомендация: когда вы сталкиваетесь с проблемами ЦП с использованием переходов CSS3, переключитесь на jQuery + плагин с улучшением анимации.

Ответ 4

Вы также можете использовать это в любом из следующих элементов класса, где вы хотите использовать GPU вместо CPU

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

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

Ответ 5

О конкретном случае "пульсирующей" фоновой анимации, о котором сообщалось здесь, я предложил решение css + js.

В моем случае фоновая анимация была на свойстве background-position, а не background-color, но принцип тот же.

Хорошо, допустим, у вас есть блок с определенным фоном:

<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:

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) Обратите внимание, чтобы правильно рассчитать секунды для перехода и тайм-аута как в css, так и в js, если вы хотите, чтобы значения отличались от 5 секунд.