CSS3 background-position Animation auf iOS

Sehr große Bilddateien können aufgrund von iOS Resource Limits auf iOS Geräten nicht richtig dargestellt werden, was bei CSS3 Animation zu einem Problem werden kann, hier die ganze Geschichte:

Irgendwann fiel mir diese coole Firefox Animation auf, die David Walsh nochmal genauer erklärt hat und ich wollte unbedingt bei einem Projekt die Power von CSS3 Animationen anwenden.

Die Technik

Die Technik erinnert an das Daumenkino oder einen Filmstreifen. Man definiert eine Frame-Größe zum Beispiel 200×200 Pixel und reiht dann nebeneinander die einzelnen Frames. Dadurch ergeben sich sehr breite Grafikdateien, bei der Firefox Animation zum Beispiel 7020×156 Pixel. Uff!

Damit das Hintergrundbild schrittweise verschieben werden kann, nutzen wir die CSS3 Animation Syntax mit dem steps(xx) Parameter. Dadurch wird der animierte Wert nicht von einem Status zum nächsten interpoliert sondern hart geschritten.

Das iOS Problem

In meinem Fall ist die Framegröße 600×600 Pixel mit insgesamt 48 Bildern in der Animation, wodurch die Bilddatei unglaubliche 28.800×600 Pixel also 17.28 Megapixel groß ist.

Jetzt kommt endlich das iOS Problem: Aus irgendeinem Grund unterstützt iOS keine großen Bilddateien. Hier wurde eine Grenze bei 2289×2289 entdeckt, bis zu jener die Bilder wie erwartet dargestellt werden und ab 2290×2290 wurden die Bilder plötzlich kleiner skaliert und auch in der Auflösung halbiert.

Wie anfangs erwähnt gibt es limitierte Ressourcen auf iOS Geräten, nämlich maximal 3 Megapixel für Geräte mit weniger als 256 MB RAM und 5 Megapixel für Geräte mit mehr als 256 MB RAM. Dabei ist es egal ob es ein GIF, JPG, PNG ist und wie stark es komprimiert wurde, da jedes Bild zur Darstellung dekomprimiert werden muss und dann ein 20 KB PNG und ein 120 KB JPG bei gleicher Pixelanzahl auch gleich viel Speicher belegen.

Genau in das Problem lief ich auch und der erste Fix war per background-size: 28800px 600px; die Größe festzuhämmern. Dadurch wurde die Animation wieder in der richtigen Größe angezeigt, allerdings mit starken Skalierungsartefakten, so als hätte man die Grafik in halber Größe angelegt. Das war nicht schön.

Viele Tests später habe ich rausgefunden, dass 3.600×1.800 Pixel noch ok angezeigt werden, danach (also 600 Pixel mehr hoch oder 600 Pixel mehr breit) nicht mehr funktioniert.

Die Lösung

Die Lösung ist Javascript :-/. Für iOS habe ich nun eine kleine Funktion geschrieben, die nicht mehr schrittweise die background-position ändert, sondern in jedem Schritt die Hintergrundgrafik komplett wechselt. Mit einem Preloader der alle Grafiken vorlädt gleicht das Ergebnis der korrekten CSS3 Animation Darstellung.

Die Nebenwirkungen

Leider sind die Einzelgrafiken fast doppelt so groß wie die Filmstreifen Animationsdatei und erzeugen 47 mehr GET Requests, aus WPO Sicht also ein Desaster. Da es sich bei der Anwendung um ein Spiel handelt, ist dieser Punkt vernachlässigbar, das Benutzererlebnis ist bei einem Spiel wichtiger.

Die Javascript Lösung kann sich in der Performance der Seite auch negativ niederschlagen. Aber auch hier handelt es sich um eine Willkommens-Animation, in der der Benutzer nicht mit der Seite interagieren muss, daher nehme ich auch diesen Einschlag in Kauf. Kleinere CSS3 Animationen, die während des Gameplay vorkommen, überschreiten nicht die Bildgrenzen und sind deshalb nicht auf die Javascript Lösung umgestellt worden.

Mit guter Kapselung der Anwendungslogik ist es gar nicht kompliziert gewesen allen nicht iOS Browsern die CSS3 Animation inklusive Preloading des großen Animationsbild unterzujubeln und die Einzelgrafiken inkl. Preloading nur auf iOS Geräten vorzunehmen.