Eines Tages, wenn der Internet Explorer 9 seine minderbemittelten Vorfahren aus dem Weg geräumt hat, wird SVG unsere Webdesigner-Welt sicher gründlich umkrempeln. Bis zu diesem Umkrempeln können wir Vektorgrafiken zumindest schon mal verwenden, um die Performance unserer herkömmlichen Websites zu verbessern, denn mit den richtigen Tools stört es nicht, dass IE 6 bis 8 kein SVG beherrschen. Wenn die Umstände stimmen, kann man mit clientseitig generierten Vektorgrafiken ein paar Kilobytes einsparen und einige Nachteile, die traditionelle Optimierungsmethoden mit sich bringen, elegant umschiffen.

Performance-Optimierung von Grafiken heute

CSS-Sprites gelten heutzutage als die erste Maßnahme zur Reduzierung von HTTP-Requests. Fasst man alle Grafiken einer Website in nur einer großen Datei zusammen, gibt es auch nur einen einzigen Download und gegebenenfalls weitere Ersparnisse durch eine gemeinsame Farbpalette. Zu den Nachteilen gehören ein umständliches Handling der Datei und enormer Arbeitsspeicher-Verbrauch beim Empfänger. Die Alternative zu Sprites wäre Base64-Inlining, also das Einbetten der Grafiken in CSS-Dateien. Dies ist aber ohne die richtigen Tools (wie dieses hier) ebenfalls recht mühsam und dass dabei die Dateigröße jeder Grafik um etwa 33% aufgebläht wird, ist dem ursprüngliche Ziel der Performanceverbessung nicht gerade dienlich. Was also tun?

Viel lässt sich mit CSS3 einsparen. Wenn Farbverläufe und Schatten vom Browser errechnet werden können, müssen hierfür nur ein paar Zeilen Code durch die Leitung geschickt werden, was natürlich wesentlich flotter ist, also eine wie auch immer optimierte Grafik zu senden. Aber Browser können nicht nur CSS3! Da seit geraumer Zeit JavaScript-Performance das VerkaufsArgument für Browser schlechthin ist und sich Opera, Webkit und Mozilla wöchentlich mit immer neuen Optimierungen überbieten, könnte man dieses Potenzial doch mal zur Performanceoptimierung abrufen. Ich mache das seit geraumer Zeit, indem ich, wo immer es sinnvoll ist, Bilder als Vektorgrafiken via Javascript clientseitig generieren lasse – ergänzend zu herkömmlichen Techniken. Zwar ist, bis der Internet Explorer 8 eines Tages ausgestorben ist, SVG noch nicht überall einsetzbar, doch das muss nicht stören.

Raphaël rettet

Die älteren Internet Explorer unterstützen kein SVG, aber etwas entfernt ähnliches: VML, Vector Markup Language. VML ist SVG insofern ähnlich, als dass es hierbei auch um in XML formulierte Vektorgrafiken handelt, allerdings ist VML in der Praxis nicht weniger als die ungefilterte Essenz des Bösen – Markup und API sind so schrecklich, wie es eben nur Microsoft Anno 1998 zustande bringen konnte. Und dass VML komplett inkompatibel zu SVG ist, macht die Sache noch unhandlicher.

Abhilfe schafft eine Javascript-Bibliothek namens Raphaël, die eine einheitliche API für Web-Vektorgrafiken bereitstellt. An Raphaël erteilt man als Programmierer generelle Befehle (z.B. „zeiche einen Kreis“) und die Umsetzung und Einbettung übernimmt das Script. Je nach zur Verfügung stehendem Browser werden VML oder SVG und die diversen Einbettungsmöglichkeiten vom einfachen <object> bis hin zu <svg> aus HTML5 genutzt. Der Effekt: als Webworker kann man Vektorgrafiken einsetzen, ohne über Browser oder Technologien nachdenken zu müssen. Im folgenden Video stellt Raphaël-Macher Dmitry Baranovskiy sein Werk vor und lässt unterhaltsame Fun Facts zu VML vom Stapel:

Raphaël kann man einsetzen um flashige Charts und „HTML5-Demos“ zu bauen oder um eine bessere Druckqualität zu erreichen. Oder man kann Bytes beim Kampf um bessere Performance sparen, indem man clientseitig Grafiken mit JavaScript erzeugen lässt.

Einmal durchgerechnet

Raphaël selbst wiegt gezippt und minifiziert 20 Kb. Hinzu kommt die eigentliche Programmierung der Grafiken selbst. Das ist viel Holz und bedeutet, dass man mindestens 20 Kb an herkömmlichen Grafiken überhaupt zu ersetzen haben sollte. Hat man weniger Material, lohnt es sich vermutlich nicht. Danach könnte es sich aber rechnen. Nehmen wir zum Beispiel folgendes Bild:

Das Internet-Explorer-Logo

Dies ist ein halbherzig optimiertes (1× mit OptiPNG drübergebügelt) PNG mit einem Motiv, das sich zur Vektorisierung anbietet. So wie es da als 8-Bit-PNG ist, schlägt es sich mit knapp 3,2 Kb und einem HTTP-Request zu Buche, Base64-codiert und gezippt ist es minimal mehr, dann aber ohne zusätzlichen Request. Verwandelt man das Bild aber in einen SVG-Pfad, landet man (wieder gezippt und ohne besondere Optimierungs-Anstrengungen) bei 1,2 Kb, spart also fast 2/3 ein. Der Code, der zur Einbindung in Raphaël zusätzlich nötig ist, ist minimal:

window.onload =  function(){
    var canvas = Raphael("grafik", 141, 145);
    var logo = canvas.path("M 119.59375 0 C 108.674 0.24766846 ... L 120.0625 123.59375 L 120.0625 121.375 z");
    logo.attr({
        stroke: null,
        fill: '#37a5e2'
    });
}

Im direkten Vergleich (Oldschool, Vektor) kommt die Vektorlösung insgesamt bei unserem Beispiel nicht so gut weg, da sie schließlich die 20 Kb von Raphaël mit sich herumschleppt. Vergleicht man aber nur die für die Grafik verantwortlichen Komponenten, so landet man bei 3,2 Kb für die CSS-Datei des Oldschool-Beispiels und bei nur 1,3 Kb für die Scriptdatei beim Vektor-Beispiel. Das ist für sich betrachtet eine beachtliche Ersparnis.

Die 20 Kb von Raphaël zu kompensieren heißt nicht zwingend, dass man mindestens 10 solcher Bilder durch Scripts ersetzen muss, damit sich das Ganze rechnet – auf die Umstände kommt es an:

  • Bei gewissen Bild-Typen (z.B. bei Farbverläufen oder besonders großformatigen Bildern) hängen Vektorgrafiken Rastergrafiken wesentlich deutlicher ab.
  • Animationen wie z.B. Ajax-Loader sind mit Raphaël immer performanter und auch schöner umzusetzen als mit GIFs
  • Falls man in einem Design die Gelegenheit hat, Formen zu recyclen, hat man aus Vektorsicht den Jackpot geknackt. So könnte etwa jede Grafik, die in diesem Blogdesign die Blatt-Form verwendet, komplett durch Raphaël ersetzt werden und jeweils aus ein und demselben SVG-Pfad erstellt werden.
  • Auch wenn man mehrere Varianten einer Grafik benötigt, z.B. um die verschiedenen Breiten eines flexiblen Layouts zu bedienen, rechnet sich die Vektorlösung.

Wenn ein paar dieser Umstände zutreffen, kann sich Weg der generierten Vektorgrafiken sehr schnell lohnen.

Vor- und Nachteile

Ein großer Bonus von clientseitig generierten Vektorgrafiken ist (neben dem Einsparen einiger Bytes) das No-Brainer-Inlining. Zusätzliche HTTP-Requests fallen, da die Grafiken ja JavaScript sind, prinzipbedingt nicht an und anders als beim herkömmlichen Base64-Inlining von Rastergrafiken muss man auch keinen Gedanken an den IE verschwenden – Raphaël übernimmt das alles. Außerdem genießt man alle weiteren Vorteile von Vektorgrafiken wie etwa die bessere Druckqualität oder die Tatsache, dass die Raphaël-Konstruktionen verlustfrei skalieren.

Nachteilig ist in erster Linie, dass das Jonglieren mit den SVG-Pfaden ist ähnlich umständlich ist wie das Hantieren mit CSS-Sprites. Man muss eine SVG-Datei händisch öffnen, den Pfad/die Pfade ausfindig machen, in eine JS-Datei hineinkopieren und dann auch noch die Grafikerstellung selbst programmieren. Da könnte eine Art Templating Engine, die Pfadinformationen automatisch aus SVG-Dateien extrahiert, ein wenig helfen:

canvas.path("{{quelle.svg#idDesElementsMitDemPfad}}");

Allerdings war mein persönlicher Leidensdruck bisher noch nicht so groß, dass ich mich zu Programmierung von so etwas haben aufraffen können.

Dass die durch Scripts generierten Grafiken bei Usern mit abgeschaltetem JavaScript nicht zu sehen sind, ist meines Erachtens kein großes Problem – man darf heutzutage erwarten, dass ein Webdesigner sein CSS so auslegt, dass es auch ohne Grafiken benutzbar bleibt. Ob diese Grafiken dann fehlen, weil jemand JS deaktiviert oder weil jemand Grafiken abgeschaltet hat, ist unerheblich.

Fazit

Der größte Haken von generierten Vektorgrafikenals Maßnahme zur Performanceoptimierung ist, dass sie sich, anders als CSS-Sprites nicht immer lohnen. Wenn aber die richtigen Umstände vorliegen – viele vektortaugliche Grafiken, sich wiederholende Elemente, Animationen – ist Raphaël ein Tool von vielen (erneut sei auf den unverzeichtbaren Booster verwiesen), das man sich in den Performance-Werkzeugkoffer legen kann.

Und wenn einen mal die Performance völlig Schnuppe ist, kann man Raphaël natürlich auch für mehr als nur platzsparende, statische Bilder verwenden. Raphaël rockt generell.