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:

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.
Kommentare (19)
sebbo ¶
21. September 2010, 07:32 Uhr
Für einfache SVGs kann man das PHP-Script hier verwenden. Das Script ist wirklich sehr eingeschränkt aber für kleine Vektorgrafiken ohne Text und ohne Bilder sollte es reichen. Animationen gingen glaube ich auch nicht...
Michael Grafl ¶
21. September 2010, 08:35 Uhr
Doch, ist eh interessant. Aber ein bisschen viel zu verarbeiten.
Anselm ¶
21. September 2010, 08:44 Uhr
Kannst du vielleicht nochmal was über das Schreiben der Grafiken schreiben? Ich finde das Thema sehr interessant.... =)
Bertram Simon ¶
21. September 2010, 11:32 Uhr
Ich mag SVG, weil es die Arbeit mit wirklich großen Bildern ermöglicht. Raphaël kannte ich noch nicht, vielleicht setzte ich es bei dem Relaunch meiner Website ein. Auf jeden Fall danke für den tollen Artikel!
wumble ¶
21. September 2010, 11:36 Uhr
Nach kurzem lesen der Doku, reichen da ja anscheinend schon die drei Zeilen um das als Vektor zu bekommen:
coole Sache! Bisher Raphael irgendiwe nie beachtet, danke!
wumble ¶
21. September 2010, 11:38 Uhr
ok doch nicht ganz.. egal.. mal bei Gelegenheit weiter anschauen
Chris ¶
21. September 2010, 12:06 Uhr
SVG ist super, aber man sollte dennoch einige Dinge bedenken:
1. Was ist wenn JS abgeschaltet ist?
2. Was ist mit Grafiken die Inhalt besitzen? (Thema alt-Attribut und Barrierefreiheit)
3. Soweit ich das gesehen habe, ist bei den SVG's seiner Seite ( http://raphaeljs.com/ ) überall ein "desc"-Tag drin mit seinem Namen, das ist natürlich nicht so prickelnd ;)
4. Was ist wenn die Browser das endlich komplett (auch inline) unterstützen? Dann ist theoretisch die Lib "sinnlos".
Ansonsten bin ich voll und ganz ein Fan von SVG und werde mir das näher anschauen. :-) Für Grafiken ohne Inhalt (z.B. Icons) ist das sicherlich ein Test wert.
Gruß
Chris
Peter ¶
21. September 2010, 12:21 Uhr
Dann fehlen ein paar Bilder. Wen stört's sofern die Seite bedienbar bleibt.
HTML5-Elemente
<figure>
und<figcaption>
? Ansonsten halt auslassen, wobei ich eh sagen würde dass diese Vektorgeschichte mehr was für Grafiken mit rein dekorativer Funktion ist.Wer sowas programmiert, der darf das.
Nicht unbedingt. Erstens hat Raphaël auch sehr schöne und komfortable Animations-Funktionen, zweitens gibt es auch bei SVG Unterschiede in den Browser-Implementierungen (und wird es immer geben) und drittens erspart man sich bei generierten SVGs das ganze Boilerplate-XML, das man sonst auch über die Leitung jagen müsste.
Chris ¶
21. September 2010, 12:35 Uhr
Ok, danke für die ausführlichen Antworten. ;)
Ich bin überzeugt davon, dass SVG sinnvoll ist, sofern man es dafür einsetzt wofür es auch gedacht ist: Für grafische Zwecke in Form von Icons und deren Animation.
Allerdings bin ich noch etwas unsicher ob es sinnvoll ist soetwas wie Schatten, abgerundete Ecken per SVG zu machen. Da läge dann die Last wirklich wieder Clientseitig und per CSS wäre dies - wenn auch nicht Browserübergreifend - besser. Oder?
Peter ¶
21. September 2010, 13:02 Uhr
Die 20Kb von Raphaël relativieren sich sehr schnell, da sie nach dem ersten Aufruf im Browser Cache liegen und nicht mehr neu geladen werden. So mags beim ersten Aufruf etwas länger dauern, danach gehts aber deutlich zügiger, da sogar der zusätzliche request gespart wird.
Bertram Simon ¶
21. September 2010, 13:35 Uhr
Zitat Anselm:
Darüber habe ich mal gebloggt, für den Anfang sollte es weiterhelfen:
http://simonwpt.blogspot.com/2010/01/svg-vektorgrafik-mit.html
Gerrit van Aaken ¶
21. September 2010, 16:01 Uhr
Ein bisschen Realitätsfern ist’s trotzdem. Bisher verwendet man Bilddateien auf Websites für zwei Zwecke:
1. Inhaltliche Bilder. Dies sind meistens fotografische Motive, die man nicht sinnvoll vektorisieren kann.
2. Schmuckbilder. Diese sollten eigentlich als CSS-Hintergrundgrafiken eingefügt werden.
Beiden Fällen kann die SVG-Lösung nicht gerecht werden. Die einzigen beiden Fälle sind also Logos (sofern vektorisierbar – da gibt’s ja auch einen Trend hin zu aufwändigen Pixellogos), sowie Charts und Infografiken.
Fazit: In der täglichen redaktionellen Arbeit der vielbesuchten Websites werden wir SVGs nur in Ausnahmefällen antreffen.
Peter ¶
21. September 2010, 16:20 Uhr
Also die Schlussfolgerung kann ich nicht nicht nachvollziehen. Selbst wenn man davon ausgeht, dass man früher/bisher fast nur Fotos als inhaltliche Bilder verwendet hat, heißt das noch lange nicht, dass das so bleiben muss. Und Schmuckbilder als Hintergrundgrafik … aber tendenziell ja, aber wenn der andere Weg was bringt, warum nicht?
Alle Leute reduzieren das Thema SVG auf Charts. Merke ich auch jedes Mal wenn ich einen HTML5-Vortag halte und das Thema kommt – Charts und Infografiken, sonst kann sich keiner was damit vorstellen. Komischerweise gibt's diese Denksperre bei Canvas nicht.
antpaw ¶
21. September 2010, 16:54 Uhr
So noch ein bisschen meinen Flash Senf dazu. Man kann mit etwas js fu 9 slice scale feature (wie bei Flash) für jede svg shape einbauen. Man hat echte Masken (wie bei Flash) mit denen man sehr interessante Effekte erzielen, aber pssst.
Für druck kann man immer noch ein media="print" stylesheet einbinden mit den ganzen high dpi grafiken. Aber vector ist trotzdem immer schöner im druck.
Gerrit van Aaken ¶
21. September 2010, 17:49 Uhr
@Peter: Wieso Denksperre? Was ist denn außer Charts und Logos noch so möglich mit SVG? Animationen und Interaktionen zählen jetzt mal nicht, denn im Artikel ging es ja darum, Pixelbilder zu ersetzen...
Und dass reine Schmuckbildchen (wie zum Beispiel die verwendeten Grafiken für die Kommentar-Kästchen bei dir im Blog) eigentlich nichts im HTML zu suchen haben, dürfte klar sein, oder?
Peter ¶
21. September 2010, 18:06 Uhr
Sind ja nicht in HTML, sind in Scripts. Ja, da gehört derartiges eigentlich auch nicht rein, aber die Welt ist ja auch angesichts von
$('#foo').setStyle(xyz).animate()
noch nicht untergegangen.Schepp ¶
21. September 2010, 18:20 Uhr
Ich vermute, Gerrit zielt darauf ab, dass dekorative Grafiken, egal ob sie nun schon vorher drin sind oder onload erst erzeugt werden, am Ende als Elemente im DOM-Baum landen. Und als Verfechter der Inhalte-Layout-Trennung mag ihm das nicht so recht gefallen.
Chris ¶
22. September 2010, 06:27 Uhr
Wenn ihr aber von Inhalt-Layout-Trennung sprecht, wieso gibt es dann letzenendes Inline-SVG, welches immer mehr implementiert wird? Und um eins drauf zu setzen, ist es wohl dann korrekt SVG's über das object-Tag einzubinden?
In der Spec steht:
Was bedeutet: Inhalt wird ausgezeichnet, da ist wohl das Einbinden über ein object-Tag eher falsch (Vergleichbar mit einem img mit Text und ohne alt-Attribut).
Ich finde es ok inline-SVG zu verwenden und der Vorlesebrowser stört sich daran auch nicht. Ebenso ist es von Vorteil das man httpRequests spart und "hochauflösende" Grafiken hat.
Nachteil ist, wenn man wirklich seine Icons ersetzenw ill, es ziemlich viele Icons sein müssen damit es sich von der Dateigröße her lohnt (Es wäre interessant, wenn du uns mal verraten könntest wieviel KB deine kompletten Icons ausmachen die du durch dieses Script ersetzen könntest Peter).
Gruß
Chris
Andreas Fritsch ¶
22. September 2010, 07:14 Uhr
Wenn man vorhat, mit der Grafik zusätzliche Interaktionen anzubieten, die ohnehin nur mit JS möglich sind, kann man über Raphaël nachdenken. Ich persönlich finde es eher mühsam, händisch die Pfade zu übernehmen und kann mir diesen Aufwand nur in Ausnahmefällen vorstellen. AmpleSDK finde ich praktischer, da man damit die SVG direkt in ein script-Element einbetten kann.
Ein Foto sollte immer ein Foto bleiben, den meisten Bildelementen auf vielen Seiten sieht man ihre Vektorherkunft aber noch an (z.B. auf mailchimp). Kleine Icons usw. kann man schon jetzt via CSS definieren, da dies alle kommenden Browser wie IE9 und Fox4 verstehen und Opera und Webkit sowieso schon lange.
Leider sind SVG-Sprites nicht möglich.
Für eine sanfte Migration bietet sich die Inline-Einbettung an, mit zusätzlichen switch/foreignObject für alternativen Content.
Hier mal mein Beispiel, wie das unproblematisch und für die meisten Endgeräte geht. Das vektorisiserte IE-Symbol konvertiert man relativ problemlos via Inkscape/odg/OO/Winword in VML.