Webseiten-Ladezeit verringern: Bilder per CSS im Base64-Code in Webseite einbinden

Eine Möglichkeit die Geschwindigkeit einer Webseite zu erhöhen ist, die Bilder nicht als einzelne Dateien, sondern Base64-codiert innerhalb der CSS-Datei zu führen.

Ich optimiere gerade lustig an themenmix.de herum. Auslöser für den Kampf um jede Millisekunde war die eklatant lange Zeit, die themenmix.de zum Laden brauchte. Ich hatte das mal über nen Tag verfolgt und stets Ladezeiten zwischen 12-15sec gehabt. Absolut inakzeptabel. Ich kam auf die Idee, kleinere Bilder innerhalb der CSS-Datei einzulagern. Mittels CSS und der Base64-Codierung ist das eine saubere Lösung.

Eine Ursache für die langen Ladezeiten sind viele HTTP-Requests, die der Browser an den Webserver der Seite schicken muss, die du dir ansehen willst. Jede Datei wird einzeln vom Webserver angefordert. Je mehr Dateien eine Webseite enthält, desto mehr Request sind nötig, um die Webseite komplett zu laden.

Social-Media vs. Website-Performance

Nun besteht themenmix.de eigentlich aus nicht allzu vielen Dateien. Jede Seite besteht aus einem eigenen Artikelbild, mehr oder weniger weiteren Bildern und dem Text. Da ist nicht viel Optimierungspotential. Es gibt dennoch wiederkehrende Elemente, die auf jeder einzelnen Seite vorkommen: die Social-Media-Icons für Facebook, Twitter, Google+ etc. Es gibt viele Plugins und Widgets, die dem Blogbetreiber das Tor zur Social Media Welt aufstoßen. Um möglichst viel Interaktion mit meinen Besuchern zu erreichen hatte ich zeitweise 4 verschiedene Plugins und Widgets in WordPress eingebunden, welche die Seite mit Like-Buttons, Share-Button, Twitter-Follow-me-Button und weiterem Schnickschnack befeuerten. Vor dem Artikel, unterhalb jedes Artikels und in der Sidebar konnte man Sharen, Liken und Plussen und Zwitschern.

Doch dies hatte seinen Preis. Viele Plugins holen sich beim Seitenaufbau Daten vom Social-Network: die Anzahl der Follower, der Likes u.s.w. Auch diese Daten müssen beim Seitenaufbau erst einmal angefordert werden. Das kostet Zeit. Viel Zeit.
Ich entschloss mich daher, meinem Ego nicht mehr genüge zu tun und mit möglichst viel Likes und Tweets anzugeben, sondern wollte auf einfache Buttons setzen.

Diese kommen vom Social Media Widget, welches ich für geraume Zeit genutzt habe. Die schicken Icons werden bei jedem Seitenaufruf geladen. Gut – einmal geladen landen sie im Cache des aufrufenden Browsers und werden fortan von dort geladen. Für neue Besucher aber müssen sie erst einmal dorthin transportiert werden. 6 Bilder sind dann gleich mal 6 HTTP-Request, die notwendig sind. Da die Browser nur eine begrenzte Zahl Requests gleichzeitig an einen Webserver schicken können, entsteht unter Umständen eine Art „Warteschlange“, deren Abarbeitung wiederum Zeit kostet. Zeit, welche die wenigsten Besucher im Internet haben.

Ladezeit als Rankingfaktor

Dazu kommt, dass Google inzwischen viel Wert auf die Performance einer Webseite legt und diesen Faktor in die Rankings der Suchtreffer einfließen läßt. Je schneller eine Seite lädt, desto weniger muss der Besucher warten, desto besser ist seine Experience (Benutzererfahrung bzw. das Gefühl, welches den Besucher einer Webseite überfällt) und desto besser steht Google da, weil es dem Suchenden diese tolle, schnell-ladende Seite geliefert hat. Alles ist in Butter. Somit ist bewiesen, dass Webseiten, die schnell und ohne lange Wartezeiten laden nur im Interesse von Google sein können und daher vermutlich bevorzugt behandelt werden. Für Google bedeutet das, dass die Seiten in den forderen Rängen zu finden sein werden. Was wiederum dazu führt, dass der Webseitenbetreiber sich über mehr Besucher von Google freuen kann.

Bilder in Base64-Code konvertieren und anzeigen

Wie funktioniert das jetzt mit dem Base64-Dings und dem CSS-Bums?
Die Social-Media-Buttons sind eigentlich immer Bilddateien, welche von einem Link umgeben sind:

<a href="linkziel"><img src="bilddatei" alt="beschreibung des Bildes" width="breite" height="höhe" /></a>

Das Bild können wir dabei genauso gut als „Hintergrundbild“ des a-Tags verwenden und anschließend den img-Tag eleminieren:

a.socialmedia_button {
width: 32px;
height: 32px;
-moz-transition: all 0.2s ease-in 0s;
border: 0 none !important;
display: block;
float: left;
margin-right: 10px !important;
background: #fff url(images/bild.jpg);
}

Mittels „display:block“ verwandeln wir einen normalen Link in einen Link-Kasten, den wir mittels Width und Height „aufziehen“. Der entstehende Hintergrund wird mit dem Bild url(image/bild.jpg) gefüllt. Bingo. Aber nur die halbe Miete, denn: auch dieses Bild muss erst geladen werden, erzeugt einen eigene HTTP-Request … Bringt so also nichts.

Jetzt kommt die Base64-Geschichte ins Spiel. Es gibt verschiedene Seiten im Netz, die Tools zur Base64-Codierung bereitstellen. Ich habe für die auf themenmix.de verwendeten Icons das Tool von pehbehbeh.de genutzt. Der Vorteil von dieser Lösung ist, dass man das zu konvertierende Bild-Rohmaterial nicht erst hochladen muss. Bei diesem Tool gibt man einfach die URL des Bildes an und fertig. Sehr praktisch!

Ich habe also die URL zu meinem Facebook-Button besorgt, diese in den Eingabeschlitz bei pehbehbeh.de eingefügt und „generieren“ geklickt. Das Ergebnis ist ein mordsmäßiger Zeichensalat, den ich mir kopiert habe.

Dann habe ich diesen Zeichensalat genommen und in meine CSS-Datei eingefügt. Für den Facebook-Button sieht das dann so aus:

Krass, oder? Und sowas will ein Bild sein? Ist es.
Mittels „data:image/png;base64,“ am Anfang des url()-Attributs machst du dem Webbrowser klar, dass der folgende Zeichensalat ein Image ist, welches im PNG-Format vorliegt und mit base64 codiert ist. Der Browser schnappt sich das Durcheinander und bastelt daraus wieder das Bild zusammen. Dazu braucht der Browser kein extra Addon oder Plugin. Aktuelle Browser bringen das nötige Handwerkszeug schon mit.

Welchen Vorteil bieten die Bilder als Base64-Codierung in der CSS-Datei?

Jedes, auf diese Art und Weise eingebettete Bild, spart einen HTTP-Request und damit Zeit. Die CSS-Datei wird zwar größer, doch sind die Übertragungsraten im Internet heute so schnell, dass eine größere CSS-Datei kaum ins Gewicht fällt. JEdenfalls wiegen die paar Kilobytes mehr jeden HTTP-Request locker auf. Statt der CSS-Datei und 6 Social-Media-Buttons (7 HTTP-Request) wird nur noch eine Datei (1 HTTP-Request) übertragen. Die Webseite lädt damit insgesamt schneller!

Anbieten tut sich diese Lösung nur für oft verwendete grafische Elemente einer Webseite. Grafiken und Bilder, die quasi zum Layout einer Webseite gehören. Für mich zählen die Social-Media-Buttons dazu.
Jedes einzelne Bild, welches in einem Artikel verwendet wird mittels Base64 zu codieren ist zwar möglich, aber der Aufwand dafür ist so hoch, dass es sich nicht lohnt.

Fazit

Lag ich vor dieser Aktion beim PageSpeed-Test bei 88/100 Punkten, konnte ich mittels der Base64-codierten Bilder in der CSS-Datei den Wert auf 96/100 bringen. Im Zusammenspiel mit der Abkehr von Social-Media-Countern und-Scripts hin zu festverlinkten, statischen Buttons konnte ich damit die Ladezeit von themenmix.de radikal verkürzen. Zwischendurch lud themenmix.de statt in 14sec nur noch in 5sec. Ein enormer Effekt!

11 Antworten

  1. Cedric sagt:

    Du beleuchtest die folgenden Aspekte dieser Technik leider gar nicht:

    1. Es funktioniert nicht in allen Browsern die gegenwärtig auf dem Markt sind.

    2. Du verringerst die HTTP-Abfragen auf Kosten der Datenmenge, denn ein base64-enkodiertes Bild hat alleine durch die Umwandlung des Binärinhalts in eine ASCII-Zeichenkette IMMER einen Overhead und somit eine höhe Datenmenge.

    3. Öffne eine mehrere Megabytes große CSS-Datei einmal in einem Editor und du kannst zusehen wie das Syntax-Highlighting seinen Lauf nimmt…

    Binärdaten haben durchaus ihre Daseinsberechtigung und darüber hinaus gibt es andere Mittel und Wege die HTTP-Requests zu reduzieren.

    • Themenmixer sagt:

      Hi Cedric,
      natürlich hast du recht, wenn du von megabyte-großen CSS-Dateien sprichst. Das ist sicherlich nicht Sinn der Sache. Daher nutze ich das Verfahren auch nur für kleine Dateien und auch nur für eine geringe Anzahl an Bildern. Ich habe die Erfahrung gemacht, dass die Einsparung der HTTP-Requests im Vergleich zur größeren CSS-Datei schon einiges ausmacht.

      Das mit den Browsern ist natürlich richtig. Ist ein Risiko. Jedoch kommen IE und FF damit sehr gut klar. Dummerweise stelle ich gerade fest, dass Chrome mit der Methode streikt. Verdammt. Muss ich mir was einfallen lassen. Nachdem ich den Cache im Chrome gelöscht hatte, sehe ich die Buttons auch da. 🙂

      Welche Ideen hast du denn auf Lager um die HTTP-Requests an meinen Webserver zu reduzieren?

      Viele Grüße aus FN
      Jörg

      • Cedric sagt:

        Hi Jörg,

        zur Reduzierung der HTTP-Requests (auch in älteren Browsern, insbesondere IE) bieten sich viele verschiedene Möglichkeiten an:

        1. Wie Tom geschrieben hat eine separate Subdomain verwenden und dabei darauf achten das möglichst so wenig Header-Informationen gesendet werden wie möglich (kein Cookie, kein ETag, etc.)

        2. Serverseitig mehrere CSS/JS zusammenfassen, zum Beispiel via SSI (Server Side Includes)

        3. CSS-Sprites verwenden

        4. Bei „Public Resources“ wie etwa jQuery, Prototype, etc. auf die CDNs der jeweiligen Anbieter setzen (z.B. Google, Yahoo)

        4. Mit YUICompressor die Quelltexte minifizieren.

        VG in meine zweite Heimat,
        Cedric

  2. SEOTom sagt:

    Lager Deine Bilder mal auf eine Subdomain (z.B. img.themenmixer.de) aus. Dadurch erhöhst Du die Anzahl der möglichen Requests und dürftest den gleichen Effekt ohne Erhöhung der Datenmenge erzielen. Zudem bleibt der Code schlank und sauber.

    Die meiste Zeit geht durch externe Anfragen verloren. Diese also ideal minimieren oder Vor-/Nachladen lassen.

    Gruß
    Tom

    • Themenmixer sagt:

      Hi Tom, auf die Idee mit der Subdomain bin ich noch nicht gekommen. Klingt aber gut, da ja Subdomains quasi als eigenständige Domains behandelt und damit zusätzliche Kanäle für Abfragen geöffnet werden. Muss ich ausprobieren. Danke für den Tipp!

  3. kritiker sagt:

    mal so neben bei, das sie diese seite seit 1997 betreiben wirft ein paar fragen auf !
    ist er ein internet urgestein oder nur ein schwätzer !?
    eine kurze recherche ergibt zumindest dem copyright hinweiß aus dem jahr 2002
    mit folgendem text „Dieser bunte Mix ist derzeit im Aufbau begriffen. Wir haben die Seiten dennoch bereits online gestellt,…. Jörg und Dolores“ sollte sich die seite also fünf jahre lang im aufbau befunden haben ???
    also was nun fünf jahre dazu gedichtet oder sehr sehr sehr lange aufbauphase ???

    nicht böse sein aber wenn ich sowas lese fühle ich mich herausgefordert 😉

    • Themenmixer sagt:

      Werter Kritiker,
      themenmix.de als solcher ist tatsächlich erst so alt, wie Sie treffend ermitteln konnten. Tatsächlich hatte ich meine erste Homepage bereits 1997 online. Damit akzeptiere ich den von Ihnen verliehenen Titel „Urgestein“ und neige bescheiden das Haupt. Damals hieß sie noch nicht so, war aber ein illustrer Mix verschiedener Themen. Ich erinnere mich als wäre es heute: ich trank eine Flasche Rotwein und schrieb einfach drauf los. Heraus kamen hirnrissige Texte sowie die damals üblichen Linklisten. In einem muss ich Ihnen Recht geben: die Angabe „betreibe ich themenmix.de seit 1997“ ist korrekterweise nicht ganz richtig. Das wird auch umgehend korrigiert. Ich bin zwar gern ein schreibender Schwätzer (ich begrüße, dass Sie dies ebenfalls erkannt haben); aber ich fühle mich auch durch Ihre Kritik angetrieben, der schonungslosen Wahrheit Genüge zu tun. Daher räume ich den unglaublichen Fauxpas bei der Angabe der Lebenszeit von themenmix.de ein und freue mich einfach über dermaßen aufmerksame Besucher! Außerdem muss ich mal schauen, ob ich nicht die alte Homepage noch irgendwo auftreiben kann. Jetzt haben Sie mich aber gepackt! 🙂

    • Themenmixer sagt:

      Noch was: Vielen Dank für die Geburtstagserinnerung: themenmix.de wird dieses Jahr 10 Jahre alt! Hossa, das wäre fast untergegangen!

  4. kritiker sagt:

    ich bemerke das sie recht gut mit solcher kritik umgehen können, sie kennen das bestimmt auch wenn man viel im netz unterwegs ist kommen einem viele selbsternannte „internet urgesteine“ unter, ich entschuldige mich für meine etwas plumpe und harsche art.
    haben sie nachsicht mit mir ich bin wahrscheinlich nur halb so alt wie sie und manchmal etwas vorlaut 😉

    das sie so konsequent waren und den betreffenden absatz sofort geändert haben
    rechne ich ihnen hoch an, ich habe erwartet das der kommentar nicht freigegeben wird.

    natürlich wünsche ich ihnen zum zehnten geburtstag alles gute, zehn jahre im internet sind eine verdammt lange zeit, das wissen wir scheinbar beide, nebenbei ich habe eine ähnliche nebenbeschäftigung wie sie daher auch meine aufmerksamkeit 😉

    zum eigentlichen thema wollte ich dann natürlich auch gerne etwas loswerden,
    wenn ich schon so unverschämt präsent bin.

    um die ladezeiten einer webseite so gering wie möglich zu halten sollten mehrere dinge umgesetzt werden,

    HTML – weniger ist mehr, sauber, logisch aufgebaut, so viel css nutzen wie möglich und auf grafiken verzichten, wenn grafiken in einem ordentlichen format und diese dann komprimieren
    CSS – style verkettung, sprites verwenden, mehrere style sheets verschmelzen
    JS – das gleiche in grün (bis auf die sprites) und bzw. oder content / styles dynamisch nachladen
    SERVER – grafiken, css, js auf eine cookie freie domain auslagern, cache verhalten richtig setzen, nicht benötigte header unterdrücken, gzip oder ähnliche komprimierung verwenden, oder ab in die cloud oder ein cdn.
    für den client optimieren und nur spezifischen content/styles/code ausliefern,
    kommentare und nicht benötigte abschnitte sowie whitespaces und ähnliches
    sollten vor dem ausliefern an den client entfernt werden (minified)

    “Public Resources” nutzen ist so ne sache weil man da wieder auf einen dritten angewiesen ist, lieber im haus behalten da hat man die kontrolle über daten/code und verfügbarkeit, ich würde sogar soweit gehen und sagen das man auf diese komplett verzichten sollte

    was die sache mit den subdomains angeht, kann man auch noch ein bissl weiter gehen und seine subdomains statisch oder dynamisch folgend erzeugen :
    1.static.domain.tld
    2.static.domain.tld
    3…… usw,
    gut für den roundtrip 😉

    was die geschichte mit google angeht, mich wundert das der tolle „SEOTom“ nichts dazu zu sagen hatte, wieso sollte google eine webseite mit hoher auslieferungs geschwindigkeit denn signifikant bevorzugen, sollte es nicht signifikant sein ist es auch kein wirklicher ranking faktor, ausserdem steht google ja mittlerweile sehr auf content und lässt sich nicht mehr so gut mit mfa seiten abspeisen was einem den fokus auf einen hochwertigen und gut strukturierten content sowie einer klaren informations architektur und sauberen verlinkungen intern wie extern, stimmen diese dinge geht es bei den oben erwähnten methoden vorrangig um die optimierung der last und des traffics und ein bisschen um den client aber nicht um google zu gefallen, (so weit kommt es noch)

    wir können aber gerne das thema optimierung gerne noch ein bisschen vertiefen und weiter diskutieren für heute muss es aber reichen ich hab feierabend
    in diesem sinne alles gute und grüße aus bn

    • kritiker sagt:

      nachtrag: die klein schreibweise ist beabsichtigt, rechtschreibfehler sind durch die späte uhrzeit bedingt, ich bitte diese zu entschuldigen denn sie sind peinlich genug (man sollte vor dem versende korrektur lesen ;))

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.