Ich verwende die folgende Keyframe-Animation für mehrere Elemente:
@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;
}
Auf meinem Computer habe ich sowohl in Chrome als auch in Firefox eine CPU-Auslastung von ca. 40%. Ist es der aktuelle Stand der Animationen (nett, aber momentan nicht verwendbar) oder fehlt mir eine magische Eigenschaft?
Sie können das folgende Beispiel mit derselben Animation überprüfen: http://jsfiddle.net/Nrp6Q/
move box-shadow property to pseudoelement and animate it's opacity and transform properties
Ich weiß, dass die Frage des OP ziemlich alt ist, aber könnten Sie ein Beispiel oder eine Referenz angeben ?Antworten:
Ja, dies ist normal, da die Seite mehrere Endlosschleifenanimationen enthält. Die CPU arbeitet daher kontinuierlich, während diese Elemente gerendert werden. Es gibt eine "magische" Eigenschaft, die die CPU-Auslastung erheblich reduziert, und zwar:
transform: translateZ(0);
Dadurch werden die Elemente zu eigenen Ebenen zusammengefasst (indem der Browser zu der Annahme verleitet wird, dass 3D-Transformationen durchgeführt werden), und der Browser sollte in den meisten Fällen die GPU-Beschleunigung nutzen, um die CPU zu entlasten. Für mich hat sich das um etwa 20% (fast die Hälfte) verringert.
Weitere Informationen zu dieser Technik finden Sie unter: http://ariya.blogspot.com/2011/07/fluid-animation-with-accelerated.html
Je mehr Keyframes Sie in der Animation haben, desto anstrengender wird es auch. Probieren Sie einfach die Animation mit ausgeschnittenem mittleren Keyframe aus und Sie werden einen weiteren erheblichen Rückgang (~ 10-12%) der CPU-Auslastung feststellen.
Schließlich sind nicht alle Eigenschaften gleich - Box-Shadow ist für den Browser viel schwieriger zu animieren als beispielsweise Hintergrundfarben. Wenn Sie alle Keyframes intakt lassen, aber die Box-Shadow-Eigenschaft mit dem Trick translateZ (0) löschen, lag meine CPU-Auslastung nur bei 10-11%.
So sehr es mich auch schmerzt, dies zu sagen, für Animationen mit Endlosschleifen wird eine animierte GIF-Datei im aktuellen Status der Browseranimation viel, viel besser als CSS3 funktionieren, insbesondere wenn Sie vorhaben, dass viele davon auf der Website gerendert bleiben Seite für einige Zeit.
Update 2017:
Für diejenigen, die immer noch den Weg zu dieser Frage und Antwort finden,
translate3d(0, 0, 0)
bietet dies den gleichen Vorteil wietranslateZ(0)
, Sie setzen nurtranslateX()
undtranslateY()
zur gleichen Zeit. Bitte ignorieren Sie den Kommentar von @Farside, wie er ihntranslate3d(X, Y, Z)
in seiner Demo verwendet, aber nicht mit ihmtranslate(X, Y)
, was zeigen würde, dass die Verwendung dieser Technik immer noch einen signifikanten Unterschied macht.Nach dieser Frage haben einige Leute eine bessere Leistung in allen Browsern gefunden, insbesondere in Chrome
transform: rotateZ(360deg)
.quelle
translateZ(0)
. Es scheint mir, dass CSS-Animationen derzeit eine schlechte Idee sind, da sie bei einfachen Animationen mit trivialem Quadrat die CPU stark aufheizen.translateZ(0)
, sondern zeigt nurtranslate3d(x, y, z)
. Wenn Sie das mit nur vergleichentranslate(x, y)
, würden Sie den signifikanten Unterschied sehen, den diese Methode immer noch macht.Eine der möglichen Möglichkeiten, die CPU-Belastung zu reduzieren, ist die Verwendung einer sogenannten CPU
null transform hack
, die oft als eine Art Silberkugel bezeichnet wird . In vielen Fällen wird die Renderleistung in WebKit- und Blink-Browsern wie Chrome, Opera und Safari drastisch verbessert.Verwendung des "Null Transform Hack" (ein Hardware-Compositing-Modus)
Der Null-Transformations-Hack macht im Grunde zwei Dinge:
Um einen Browser zu "erzwingen", fügen Sie dem Element einfach eine dieser CSS-Eigenschaften hinzu:
transform: translateZ(0); /* or its friend: */ transform: translate3d(0, 0, 0);
Wenn Sie mit 3D-Transformationen arbeiten, sollten Sie auch über diese Eigenschaften verfügen , um die Leistung zu verbessern :
backface-visibility: hidden; perspective: 1000;
Vorbehalte des "Null Transform Hack"
Das Aktivieren einer Hardwarebeschleunigung in CSS3 für viele Objekte kann die Leistung beeinträchtigen! Anscheinend erzeugt jede Null-3D-Transformation eine neue Ebene. Die Erstellung von Force-Hacking-Ebenen ist jedoch möglicherweise nicht immer die Lösung für bestimmte Leistungsengpässe auf einer Seite. Layer-Erstellungstechniken können die Seitengeschwindigkeit erhöhen, sind jedoch mit Kosten verbunden: Sie belegen Speicherplatz im System-RAM und auf der GPU. Selbst wenn die GPU gute Arbeit leistet, kann die Übertragung vieler Objekte ein Problem darstellen, sodass sich die Verwendung der GPU-Beschleunigung möglicherweise nicht lohnt. Das Zitat von W3C :
Das Verschieben einiger großer Objekte hat eine höhere Leistung als das Verschieben vieler kleiner Objekte bei Verwendung der 3D-Beschleunigung. So müssen sie mit Bedacht verwendet werden , und Sie müssen sicherstellen , dass die Hardware-Beschleunigung der Operation wirklich die Leistung Ihrer Seite helfen wird, und dass eine Performance - Engpass nicht durch eine andere Operation auf Ihrer Seite verursacht wird.
Darüber hinaus wurde eine GPU speziell für die Durchführung komplexer mathematischer / geometrischer Berechnungen entwickelt, und das Auslagern von Vorgängen auf die GPU kann zu einem massiven Stromverbrauch führen . Wenn Hardware aktiviert wird, wird natürlich auch der Akku des Zielgeräts aktiviert.
Der moderne Weg: das
will-change
AnwesenDer Fortschritt steht nicht an einer Stelle ... W3C hat die
will-change
CSS-Eigenschaft eingeführt. Um es kurz zu machen: Mit derwill-change
Eigenschaft können Sie den Browser im Voraus darüber informieren, welche Art von Änderungen Sie wahrscheinlich an einem Element vornehmen, damit er die entsprechenden Optimierungen vornehmen kann, bevor sie benötigt werden.Folgendes sagen sie im Entwurf :
Wenn Sie
will-change
dem Browser einen Hinweis auf eine bevorstehende Umwandlung geben, können Sie diese Regel einfach zu dem Element hinzufügen, dessen Umwandlung Sie erwarten:will-change: transform;
Bei der Entwicklung für Mobilgeräte müssen Entwickler beim Schreiben mobiler Webanwendungen die zahlreichen Geräteeinschränkungen berücksichtigen. Browser werden schlauer, und manchmal ist es besser, die Entscheidung der Plattform selbst zu überlassen, anstatt die Beschleunigung zu überlappen und das Verhalten auf hackige Weise zu erzwingen.
quelle
will-change
- ist nicht meine Empfehlung, aber es ist eine elegantere und modernere Art, "dem Browser einen Hinweis auf die bevorstehende Transformation zu geben" , anstatt ihn zu erzwingen. "als eine Art Silberkugel gepriesen" - gehört zu dem sogenanntennull transform hack
und nicht zumwill-change
Eigentum, wie Sie sagen. Ich bin in Ordnung mit Ihrer Abwahl, ich verstehe, dass Sie Angst vor der Konkurrenz haben könnten;)Ich hatte einen ähnlichen Fall von hoher CPU-Auslastung, als ich einige Elemente mit CSS3 animierte. Ich habe die "linke" Eigenschaft von ~ 7 Elementen mit einigen Deckkraft- und Schatteneigenschaften animiert, die auf meiner gesamten Seite verwendet wurden. Ich habe mich für jQuery.animate entschieden, was die Leistung leider überhaupt nicht verbessert hat. Meine CPU (i7) war beim Anzeigen der Seite immer noch bei ~ 9-15%, einige Tricks (translateZ usw.) haben die Leistung auch nicht wirklich verbessert - während mein Layout durcheinander gebracht wurde (einige absolut positionierte Elemente waren beteiligt, autsch !).
Dann bin ich auf diese wundervolle Erweiterung gestoßen: http://playground.benbarnett.net/jquery-animate-enhanced/
Ich habe einfach auf die .js-Datei verwiesen, bei den jQuery-Übergängen keine einzige Änderung vorgenommen, und meine CPU-Auslastung beträgt jetzt 1-2% auf derselben Seite.
Meine Empfehlung: Wenn Sie mit CSS3-Übergängen auf CPU-Probleme stoßen, wechseln Sie zu jQuery + dem animierten Plugin.
quelle
Sie können dies auch für eines der folgenden Klassenelemente verwenden, bei denen Sie die GPU anstelle der CPU verwenden möchten
.no-cpu { transform: translateZ(0); -webkit-transform: translateZ(0); -ms-transform: translateZ(0); } <element class="event_indicator no-cpu">animation...</element >
quelle
Für einen bestimmten Fall von "pulsierender" Hintergrundanimation, der hier berichtet wird, habe ich eine CSS + JS-Lösung entwickelt.
In meinem Fall befand sich die Hintergrundanimation eher in der Eigenschaft "Hintergrundposition" als in der Hintergrundfarbe, aber das Prinzip ist dasselbe.
Angenommen, Sie haben einen Block mit einem bestimmten Hintergrund:
<div class="nice-block">...</div>
Lassen Sie es uns stylen: (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; } }
Jetzt ist es an der Zeit, den Effekt zu erzielen, indem Sie dem Block eine Klasse 'animiert' mit etwas JavaScript hinzufügen:
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 ();
Dies verbesserte die Leistung in meinem Fall um das ~ 15-fache.
(i) Beachten Sie, dass Sie die Sekunden für Übergang und Zeitüberschreitung sowohl in CSS als auch in JS korrekt berechnen müssen, wenn Sie andere Werte als 5 Sekunden wünschen.
quelle