В 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/

4   51  

4 ответа:

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

transform: translateZ(0);

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

чтобы узнать больше об этой технике взгляните на: http://ariya.blogspot.com/2011/07/fluid-animation-with-accelerated.html

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

наконец, не все свойства равны - box-shadow намного сложнее для браузера анимировать плавно, чем, скажем, цвет фона. Оставив все ключевые кадры нетронутыми, но отбросив свойство 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).

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

использование "Null transform hack" (режим аппаратного композитинга)

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

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

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

transform: translateZ(0);

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

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

backface-visibility: hidden;
perspective: 1000;

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

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

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

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

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

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

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

вот что они говорят в the проект:

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

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

will-change: transform;

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

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

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

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

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

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

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

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