Dank CSS3 sind Animationen ohne Flash und JavaScript kein Problem mehr. Aber nicht immer kommt man mit den Möglichkeiten von CSS3 aus. Vor allem, wenn Animationen berechnet werden müssen, ist der Einsatz von JavaScript unumgänglich. Es gibt jedoch eine wesentlich performantere Möglichkeit als den Einsatz von setTimeout
und setInterval
. Denn setTimeout
und setInterval
haben den Nachteil, dass sie eine Funktion immer nach einer fest definierten Zeitspanne wiederholen. Gerade für Animationen ist ein solch fester Wert ungeeignet. Jeder, der schon einmal eine Animationen mit den beiden Funktionen programmiert hat, kennt wahrscheinlich die Schwierigkeit, den idealen Wert für die Zeitspanne in Kombination mit den jeweiligen Animationsschritten zu finden. Außerdem sind die Funktionsaufrufe per setTimeout
und setInterval
selten im Einklang mit der Bildfrequenz des Monitors, sodass nicht bei jedem Aufruf tatsächlich eine Aktualisierung der Animation dargestellt werden kann.
requestAnimationFrame
für ausgeglichene Animationen
Die Alternative, die im Rahmen von HTML5 eingeführt wurde, heißt requestAnimationFrame
. Vom Grundsatz her funktioniert sie ähnlich wie die klassische Methode – allerdings ohne Angabe einer Zeitspanne, welche die Wiederholungsrate angibt. Denn die wird vom Browser selbst festgelegt. Gerade, wenn mehrere Animationen parallel im Browser ausgeführt werden, kommt man mit setTimeout
und setInterval
schnell an die Grenzen einer flüssigen Animation. Mit requestAnimationFrame
wird die Frame-Rate – wenn nötig – automatisch heruntergesetzt, um eine flüssige Bewegung zu erhalten:
var schritt = 0;
function animation() {
schritt += 10;
document.getElementById("element").style.left = schritt + "px";
window.requestAnimationFrame(animation);
}
window.requestAnimationFrame(animation);
Im Beispiel wird ein HTML-Element in 10-Pixel-Schritten von links nach rechts animiert. Die Standard-Wiederholungsrate liegt in der Regel bei 60 Frames pro Sekunde, kann aber je nach CPU-Auslastung variieren. Der Browser versucht also nicht, an einer fixen Frame-Rate festzuhalten. Ein weiterer Vorteil von requestAnimationFrame
ist, dass Animationen nur in sichtbaren Fenstern, beziehungsweise Tabs ausgeführt werden. Sobald sich die Animation in einem nicht sichtbaren Fenster oder Tab befindet, wird sie angehalten und automatisch fortgesetzt, sobald sie wieder sichtbar ist. Um Animationen manuell anzuhalten, gibt es als Gegenstück die Funktion cancelAnimationFrame
.
Browser-Support mit Vendor-Prefix
Bislang unterstützen Webkit- und Mozilla-Browser sowie der aktuelle Internet Explorer die Funktion requestAnimationFrame
. Die Cancel-Funktion cancelAnimationFrame
wird derzeit nur von Mozilla unterstützt. Da die Funktionen noch relativ neu sind, bedarf es unterschiedlicher Schreibweisen, um alle Browser, die die Funktionen unterstützen, zu berücksichtigen. Über eine Variable kann man die richtige Schreibweise automatisch auswählen lassen:
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
Fazit: Die Performance von Animationen, die mit requestAnimationFrame
programmiert werden, spricht für sich, weshalb sie (gegebenenfalls mit einem Fallback für ältere Browser) immer den altbekannten Möglichkeiten vorgezogen werden sollte. Vor allem bei mobilen Geräten, die eine geringere Leistung haben, macht sich das bemerkbar. Einen schönen Vergleich zwischen beiden Möglichkeiten gibt es übrigens beim Test Drive des Internet Explorers! Ausgerechnet…
(dpe)
0 Antworten zu „Performantere JavaScript-Animationen mit requestAnimationFrame“
— was ist Deine Meinung?
Wenn ich das Script ansehe „schritt += 10;“
und den Satz darunter lese:
„Der Browser versucht also nicht, an einer fixen Frame-Rate festzuhalten.“
bedeutet es also, wenn der Browser das nicht schafft wird die Animation langsamer abgespielt? – also völlig ungeeignet um Animationen Zeitgebunden zu animieren – es sei man checkt immer wie viel Zeit vergangen ist und setzt die Position in Abhang der vergangenen Zeit?
Ich hab hier ein Webkit Browser Safari auf dem iPad.
Der Test Drive des Internetexplorers läuft da mit set Timeout viel flüssiger als mit requestAnimationFrame. Da erkennt man nämlich richtig das der Zeiger ruckelt. Der andere läuft schön flüssig.
Warum?
Interessante Sache. Unterstützt der IE 9 das auch? Bin mir nicht sicher, ob ihr mit „dem aktuellen Internet Explorer“ Version 9 oder 10 meint. Und Opera hat da noch nix? Dauert aber sicher auch nicht lang.