10 Prinzipien für flüssige Web-Animationen
Der komplette Leitfaden für 60-fps-Animationen mit CSS

Seit wir Gyroscope letztes Jahr gestartet haben, fragen viele nach der JavaScript-Bibliothek, die wir für unsere Animationen benutzen. Wir haben überlegt, sie zu veröffentlichen, aber dort passiert der Zauber gar nicht.
Wir wollen nicht, dass sich Leute abhängig von irgendeinem speziellen JavaScript-Plugin fühlen, das diese Probleme wie von selbst löst. Zum größten Teil nutzen wir einfach die jüngsten Fortschritte bei Browser-Performance, GPUs und der CSS3-Spezifikation.
Es gibt kein Wundermittel für gute Animationen, außer viel Zeit ins Testen und Optimieren zu stecken. Nach Jahren des Experimentierens und Ausreizens der Browser-Performance haben wir aber eine Reihe von Design- & Code-Prinzipien gefunden, die zuverlässig zu schönen Animationen führen. Mit diesen Techniken bekommst du Seiten, die sich flüssig anfühlen, in modernen Desktop- und Mobil-Browsern funktionieren und, am wichtigsten, leicht zu pflegen sind.

Technik und Umsetzung sehen bei jedem etwas anders aus, aber die grundlegenden Prinzipien helfen fast in jeder Situation.
Was ist eine Animation?
Animationen gab es schon vor dem Internet, und sie richtig gut zu machen kann ein ganzes Leben füllen. Im Web kommen allerdings ein paar besondere Grenzen und Hürden dazu.
Für flüssige 60 fps muss jedes Bild in weniger als 16 ms gerendert werden! Das ist nicht viel Zeit, wir brauchen also sehr effiziente Wege, jedes Bild zu zeichnen.
Es gibt Dutzende Wege, im Web zu animieren. Der Filmstreifen zum Beispiel ist ein Ansatz, den es schon vor dem Internet gab: leicht unterschiedliche, von Hand gezeichnete Einzelbilder, die viele Male pro Sekunde getauscht werden und so die Illusion von Bewegung erzeugen.
Twitter hat diesen einfachen Ansatz kürzlich für seine neue Herz-Animation genutzt und blättert dafür durch ein Sprite aus Einzelbildern.

Man hätte diesen Effekt auch mit einem Haufen winziger Elemente bauen können, die einzeln animiert werden, oder vielleicht als SVG. Das wäre aber unnötig kompliziert und wahrscheinlich nicht so flüssig.

In vielen Fällen willst du die CSS-Eigenschaft transition nutzen, um ein Element bei einer Änderung automatisch zu animieren. Diese Technik heißt auch „Tweening“, also das Überblenden zwischen zwei verschiedenen Werten. Ihr Vorteil: Sie lässt sich leicht abbrechen oder umkehren, ohne dass du diese Logik selbst bauen musst. Ideal für Animationen nach dem Prinzip „einstellen und vergessen“, etwa Intro-Sequenzen, oder für einfache Interaktionen wie Hover-Zustände.
Zum Weiterlesen: Alles, was du über CSS Transitions wissen musst

In anderen Fällen ist die keyframe-basierte CSS-Eigenschaft animation ideal für Details, die im Hintergrund dauerhaft laufen. Die Ringe im Gyroscope-Logo zum Beispiel drehen sich permanent. Auch Zahnradübersetzungen profitieren von der animation-Syntax.
Ohne weitere Umschweife also ein paar Tipps, die deine Animations-Performance hoffentlich deutlich verbessern…
#1
Ändere keine anderen Eigenschaften als opacity oder transform!
Auch wenn du denkst, es sei schon okay: nicht machen!
Allein dieses Grundprinzip bringt dich zu 80 % ans Ziel, sogar auf dem Handy. Du hast es vermutlich schon gehört, es ist keine originelle Idee, aber sie wird selten befolgt. Es ist das Web-Äquivalent zu „gesund essen und Sport machen“: klingt nach gutem Rat, wird aber wahrscheinlich ignoriert.
Sobald man sich an diese Denkweise gewöhnt hat, ist es ziemlich naheliegend, aber für alle, die klassische CSS-Eigenschaften animieren, ist es ein großer Sprung.
Wenn du etwas kleiner machen willst, nutzt du zum Beispiel transform: scale(), statt die Breite zu ändern. Und wenn du etwas verschieben willst, statt an margins oder paddings herumzuschrauben, was für jedes Bild das ganze Seitenlayout neu berechnen müsste, nimmst du einfach transform: translateX oder transform: translateY.
Warum funktioniert das?
Für einen Menschen klingt es nicht nach viel, width, margin oder andere Eigenschaften zu ändern, im Gegenteil, es wirkt sogar einfacher. Aber für den Computer liegen Welten dazwischen, und eine Variante ist sehr, sehr viel schlechter.
Die Browser-Teams haben enorm viel Arbeit in die Optimierung dieser Vorgänge gesteckt. Transforms lassen sich sehr effizient ausführen und können oft deine Grafikkarte nutzen, ohne die Elemente neu zu rendern.
Beim ersten Laden der Seite darfst du es krachen lassen: alle Ecken abrunden, Bilder verwenden, überall Schatten, und wenn du besonders leichtsinnig bist, sogar ein dynamischer Blur. Wenn das nur einmal passiert, spielen ein paar Millisekunden Rechenzeit keine Rolle. Aber sobald der Inhalt gerendert ist, willst du nicht dauernd alles neu berechnen.
Zum Weiterlesen: Elemente mit translate bewegen (Paul Irish)
#2
Versteck Inhalte in aller Öffentlichkeit.
Nutze pointer-events: none zusammen mit opacity 0, um Elemente zu verstecken
Hier gibt es ein paar Browser-Fallstricke, aber wenn du nur für Webkit und andere moderne Browser baust, macht es dir das Leben deutlich leichter.
Vor langer Zeit, als Animationen noch über jQuerys animate() liefen, kam ein Großteil der Komplexität beim Ein- und Ausblenden daher, zum richtigen Zeitpunkt zwischen display: none und block zu wechseln. Zu früh, und die Animation lief nicht zu Ende. Zu spät, und unsichtbare Inhalte mit opacity 0 lagen über deiner Seite. Alles brauchte Callbacks, um nach der Animation aufzuräumen.
Die CSS-Eigenschaft pointer-events (die es schon ziemlich lange gibt, die aber selten benutzt wird) sorgt im Grunde dafür, dass Dinge nicht auf Klicks oder Interaktionen reagieren, als wären sie gar nicht da. Sie lässt sich per CSS einfach an- und ausschalten, ohne Animationen zu unterbrechen oder Rendering und Sichtbarkeit zu beeinflussen.
Zusammen mit opacity 0 hat sie praktisch denselben Effekt wie display: none, aber ohne die Performance-Kosten neuer Renderings. Wenn ich etwas verstecke, setze ich meistens einfach opacity auf 0 und schalte pointer-events ab, und dann kann ich das Element vergessen, es kümmert sich um sich selbst.
Besonders gut funktioniert das mit absolut positionierten Elementen, weil du sicher sein kannst, dass sie absolut nichts anderes auf der Seite beeinflussen.
Es gibt dir außerdem etwas Spielraum, weil das Timing nicht perfekt sein muss. Es ist kein Weltuntergang, wenn ein Element eine Sekunde länger klickbar ist oder andere Dinge verdeckt, als es sichtbar war, oder wenn es erst klickbar wird, nachdem es ganz eingeblendet ist.
#3
Animiere nicht alles gleichzeitig.
Arbeite lieber mit Choreografie.
Eine einzelne Animation läuft für sich vielleicht flüssig, zusammen mit vielen anderen geht sie aber wahrscheinlich in die Knie. Eine kleine Demo, in der fast alles rundläuft, ist schnell gebaut. Diese Performance in einer kompletten Website zu halten ist um Größenordnungen schwerer. Deshalb ist gutes Timing so wichtig.
Zieh die Zeiten auseinander, damit nicht alles exakt gleichzeitig startet oder läuft. Normalerweise können sich 2 oder 3 Dinge gleichzeitig bewegen, ohne dass es langsamer wird, besonders wenn sie leicht versetzt gestartet sind. Mehr davon, und du riskierst Ruckler.
Solange auf deinen Seiten nicht buchstäblich nur eine Sache passiert, solltest du das Konzept der Choreografie verstehen. Klingt nach Tanz, ist aber beim Animieren von Oberflächen genauso wichtig. Dinge müssen aus der richtigen Richtung und zur richtigen Zeit hereinkommen. Auch wenn sie getrennt sind, sollen sie sich wie Teile eines gut entworfenen Ganzen anfühlen.
Googles Material Design hat dazu ein paar interessante Vorschläge. Das ist nicht der einzige richtige Weg, aber etwas, worüber du nachdenken und was du ausprobieren solltest.

Zum Weiterlesen: Google Material Design · Motion
#4
Leicht ansteigende transition-delays machen Choreografie einfach.
Animationen zu choreografieren ist wirklich wichtig und braucht viel Ausprobieren und Testen, bis es sich richtig anfühlt. Der Code dafür muss aber gar nicht kompliziert sein.
Ich ändere meistens eine einzige Klasse auf einem Elternelement (oft am body), um einen Schwung Transitions auszulösen, und jede hat ihr eigenes transition-delay, damit sie zur richtigen Zeit kommt. Aus Code-Sicht musst du dich nur um einen Zustandswechsel kümmern und nicht um Dutzende Timings in deinem JavaScript.

Eine Reihe von Elementen zeitversetzt starten zu lassen ist ein einfacher Weg, sie zu choreografieren. Das ist stark, weil es gleichzeitig gut aussieht und dir wertvolle Performance schenkt. Denk dran: Es sollen immer nur wenige Dinge gleichzeitig passieren. Zieh sie weit genug auseinander, damit sich jedes flüssig anfühlt, aber nicht so weit, dass das Ganze zäh wirkt. Es sollte sich genug überlappen, damit ein durchgehender Fluss entsteht und keine Kette einzelner Ereignisse.
Codebeispiel
Es gibt ein paar einfache Techniken, um Elemente zu staffeln, besonders bei langen Listen. Bei weniger als 10 Einträgen oder einer gut vorhersehbaren Menge (etwa auf einer statischen Seite) schreibe ich die Werte meistens in CSS. Das ist am einfachsten und am leichtesten zu pflegen.

Bei längeren Listen oder sehr dynamischen Inhalten lassen sich die Zeiten dynamisch setzen, indem man über die Einträge iteriert.

Meistens gibt es zwei Variablen: deine Grundverzögerung und den zeitlichen Abstand zwischen den einzelnen Elementen. Die Balance ist knifflig, aber wenn du die richtigen Zahlen triffst, fühlt es sich einfach perfekt an.
#5
Nutze einen globalen Multiplikator, um in Zeitlupe zu gestalten
Und beschleunige danach alles.
Beim Gestalten von Animationen ist Timing alles. 20 % der Arbeit steckt in der Umsetzung, die anderen 80 % darin, die richtigen Parameter & Dauern zu finden, damit alles zusammenpasst und flüssig wirkt.
Gerade wenn du mehrere Dinge choreografierst und der Seite Performance und Gleichzeitigkeit abringst, macht es vieles leichter, das Ganze in Zeitlupe zu sehen.
Ob du JavaScript nutzt oder einen CSS-Präprozessor wie SASS (den wir lieben), es sollte ziemlich einfach sein, ein bisschen zusätzliche Rechnerei einzubauen und mit Variablen zu arbeiten.
Sorg dafür, dass es bequem ist, verschiedene Geschwindigkeiten oder Zeiten auszuprobieren. Wenn eine Animation selbst bei 1/10 der Geschwindigkeit stockt, stimmt vielleicht etwas Grundlegendes nicht. Läuft sie 50-fach gedehnt flüssig, geht es nur noch darum, das höchste Tempo zu finden, bei dem sie noch sauber läuft. Ein Problem von 5 Millisekunden fällt bei voller Geschwindigkeit kaum auf, aber wenn du alles verlangsamst, springt es dir ins Auge.
Gerade bei sehr komplexen Animationen oder kniffligen Performance-Engpässen ist es wirklich nützlich, die Dinge in Zeitlupe sehen zu können.
Die Idee ist: Du packst jede Menge perfekte Details hinein, solange es langsam läuft, und beschleunigst danach das Ganze, damit es sich perfekt anfühlt. Es ist sehr subtil, aber die Nutzer merken die Geschmeidigkeit und die Details.
Diese Funktion steckt übrigens in OS X: Wenn du mit gedrückter Shift-Taste auf den Minimieren-Button oder ein App-Icon klickst, siehst du die Animation in Zeitlupe. Eine Zeit lang hatten wir diese Zeitlupe sogar in Gyroscope eingebaut, ausgelöst durch die Shift-Taste.
#6
Nimm deine UI auf Video auf und schau es dir an, das gibt dir eine wertvolle Außensicht.
Manchmal hilft eine andere Perspektive, Dinge klarer zu sehen, und Video ist dafür großartig.
Manche bauen ein Video in After Effects und versuchen dann, das auf einer Website umzusetzen. Ich gehe oft den umgekehrten Weg und versuche, aus der Oberfläche einer Website ein gutes Video zu machen.
Etwas als Vine* oder Video zu posten ist eine ziemlich hohe Hürde. Eines Tages war ich begeistert von etwas, das ich gebaut hatte, und wollte eine Aufnahme für ein paar Freunde machen.
Als ich sie mir aber noch einmal ansah, fielen mir jede Menge Dinge auf, die nicht gut waren. Es gab einen dicken Ruckler und alle Zeiten waren leicht daneben. Es war mir ein bisschen peinlich, und statt sie zu verschicken wurde mir klar, dass noch viel Arbeit vor mir lag.
Beim Benutzen in Echtzeit übersieht man so etwas leicht, aber wenn man Animationen auf Video anschaut, immer wieder oder in Zeitlupe, springen die Probleme förmlich ins Gesicht.
Man sagt, die Kamera macht 10 Pfund schwerer. Vielleicht macht sie auch 10 Frames schwerer.
Inzwischen gehört es fest zu meinem Arbeitsablauf, Zeitlupenvideos meiner Seiten anzusehen und nachzubessern, wenn sich einzelne Frames falsch anfühlen. Man schiebt es leicht auf langsame Browser, aber mit etwas mehr Optimierung und Testen lassen sich diese Probleme alle lösen.
Wenn dir Ruckler im Video nicht mehr peinlich sind und du findest, dass man das Video teilen kann, ist die Seite wahrscheinlich reif für die Veröffentlichung.
#7
Netzwerkaktivität kann ruckeln lassen.
Lade große HTTP-Anfragen vor oder verzögere sie
Bilder sind hier ein Hauptverdächtiger, egal ob ein paar große (etwa ein großer Hintergrund), unzählige kleine (stell dir 50 Avatare beim Laden vor) oder einfach viel Inhalt (eine lange Seite mit Bildern bis runter zum Footer).
Beim ersten Laden der Seite werden Unmengen Dinge initialisiert und heruntergeladen. Analytics, Werbung und andere Skripte von Dritten machen es noch schlimmer. Manchmal wirkt es Wunder, alle Animationen nach dem Laden um ein paar Hundert Millisekunden zu verzögern.
Optimier daran nicht herum, bevor es nötig ist, aber eine komplizierte Seite braucht womöglich sehr genaue Verzögerungen und Zeiten, damit sie flüssig läuft. Generell willst du am Anfang so wenig Daten wie möglich laden und den Rest der Seite erst nachladen, wenn die schwere Arbeit und die Intro-Animationen durch sind.
Bei Seiten mit vielen Daten kann allein das Laden erheblichen Aufwand bedeuten. Eine Animation, die mit statischem Inhalt gut läuft, kann auseinanderfallen, sobald gleichzeitig echte Daten geladen werden. Wenn etwas eigentlich funktionieren müsste oder mal flüssig läuft und mal nicht, würde ich die Netzwerkaktivität prüfen, um sicherzugehen, dass nicht gleichzeitig anderes passiert.
#8
Häng nichts direkt an den Scroll.
Klingt nach einer coolen Idee, ist aber keine gute.
Scroll-basierte Animationen sind in den letzten Jahren beliebt geworden, besonders solche mit Parallax oder anderen Spezialeffekten. Ob das gutes Design ist, kann man diskutieren, aber es gibt technisch bessere und schlechtere Wege.
Einigermaßen performant ist es, das Erreichen einer bestimmten Scroll-Position als Ereignis zu behandeln und Dinge einmalig auszulösen. Wenn du nicht wirklich weißt, was du tust, würde ich diese Kategorie meiden, weil so leicht etwas schiefgeht und die Pflege richtig schwer ist.
Noch schlimmer ist es, eine eigene Scrollleiste zu bauen, statt die vom Browser zu nutzen, auch bekannt als Scrolljacking. Bitte lass das.
Diese Regel ist besonders auf Mobilgeräten nützlich, aber wohl auch generell gute Praxis für ein ideales Nutzererlebnis.
Wenn du unbedingt eine bestimmte Erfahrung willst, die auf Scrollen oder besonderen Ereignissen beruht, würde ich schnell einen Prototyp bauen, um sicherzugehen, dass sie performt, bevor du viel Zeit ins Design steckst.
#9
Teste früh & oft auf dem Handy.
Die meisten Websites werden am Computer gebaut und meistens auch auf genau dieser Maschine getestet. Das mobile Erlebnis & die Animations-Performance sind deshalb oft ein nachträglicher Gedanke. Manche Techniken (etwa canvas) oder Animationsverfahren laufen mobil einfach schlechter.
Sauber programmiert & optimiert (siehe Regel #1) kann ein mobiles Erlebnis aber sogar flüssiger sein als am Computer. Mobile Optimierung war früher ein sehr kniffliges Thema, aber neue iPhones sind inzwischen schneller als die meisten Laptops! Wenn du die bisherigen Tipps befolgt hast, hast du mobil womöglich von Haus aus eine großartige Performance.

Mobile Nutzung ist bei fast jeder Website ein großer und sehr wichtiger Teil. Es klingt extrem, aber ich würde vorschlagen, sie eine ganze Woche lang ausschließlich vom Handy aus anzusehen. Es sollte sich nicht wie eine Strafe anfühlen, die mobile Version benutzen zu müssen, tut es aber oft.
Verbessere Design & Performance so lange, bis es sich genauso rund und bequem anfühlt wie die große Version der Seite.
Wenn du dich zwingst, eine Woche nur die mobile Seite zu nutzen, optimierst du sie am Ende wahrscheinlich zu einem besseren Erlebnis als die große. Der Ärger beim regelmäßigen Benutzen lohnt sich, wenn dadurch die Probleme behoben sind, bevor deine Nutzer sie erleben!
#10
Teste häufig auf mehreren Geräten
Bildschirmgröße, Pixeldichte oder Gerät können alles verändern
Neben mobil gegen Desktop gibt es viele Faktoren, die die Performance drastisch beeinflussen: ob ein Bildschirm „retina“ ist oder nicht, die Gesamtzahl der Pixel im Fenster, wie alt die Hardware ist und so weiter.
Auch wenn Chrome und Safari beide auf Webkit basieren und eine ähnliche Syntax haben, hat jeder seine Eigenheiten. Jedes Chrome-Update kann Dinge reparieren und neue Fehler einführen, du musst also ständig wachsam sein.
Natürlich willst du nicht nur für den kleinsten gemeinsamen Nenner bauen, deshalb ist es sehr nützlich, clevere Wege zu finden, Extras schrittweise zu- oder abzuschalten.
Ich wechsle regelmäßig zwischen meinem winzigen MacBook Air und meinem riesigen iMac, und jeder Wechsel bringt kleine Probleme und Verbesserungen ans Licht, besonders bei der Animations-Performance, aber auch beim Design insgesamt, bei der Informationsdichte, der Lesbarkeit und so weiter.
Media Queries sind sehr mächtige Werkzeuge für diese unterschiedlichen Fälle. Nach Höhe oder Breite unterschiedlich zu gestalten ist der klassische Einsatz, aber sie können auch nach Pixeldichte oder anderen Eigenschaften unterscheiden. Auch Betriebssystem und Gerätetyp zu erkennen kann nützlich sein, weil sich die Performance mobil stark von der am Computer unterscheidet.

Ich hoffe, diese Techniken helfen dir bei deinem nächsten Projekt. Viel Erfolg!


