Daten-URLs — eine alte (fast ausgestorbene) Wundertüte mit einer Überraschung.
Performance heutzutage ist im digitalen Zeitalter alles was zählt. Doch was ist ein Daten-URI-Schema überhaupt und was kann man damit wirklich an Geschwindigkeit raus holen?
Webseiten werden immer komplexer und die damit verbundene Performance zu einem immer wichtigeren Thema. Es gibt viele verschiedene Strategien, die man anwenden könnte, um die Leistung von Webseiten zu verbessern. Dazu gehören die Optimierung von Bildern, die Kombination mehrerer CSS-Dateien zu einer Datei oder das deklarieren (geeigneter) Cache-Header, so dass der Browser Ressourcen nicht mehrfach herunterladen muss, wenn diese sich nicht geändert haben.
Was ist also eine Daten-URL?
Eine Data-URL oder auch Data-URI besser gesagt ist eine Base64-kodierte Zeichenfolge, die eine Datei darstellt — also eine Zeichenkette, welche aus 64 möglichen Zeichen besteht. Wenn der Inhalt einer Datei als Zeichenfolge beispielsweise abgerufen wird, kann die dahinter befindende Information (oder Quellcode) direkt in dem HTML- oder CSS-Code eingebettet werden. Wenn der Browser auf eine Daten-URI im Quellcode stößt, kann dieser die Daten entschlüsseln und die Originaldatei wieder herstellen.
Daten-URIs können für alle erdenklichen Arten von verschiedenen Dateitypen eingesetzt werden. Am häufigsten wird im Web diese Funktion für Bilder (und manchmal auch für Schriftarten) verwendet.
Ein Daten-URI folgt einem bestimmten Schema (wie folgt dargestellt), das neben den kodierten Daten selbst auch weitere Informationen (z.B. den MIME-Type) über die kodierte Datei enthält:
data:[<MIME-Type>][;charset=<encoding>][;base64],<data>
Im Quellcode kann man dann Data-URIs überall dort angeben, wo ein Dateipfad platziert werden könnte. Beispielsweise kann man eine Daten-URI verwenden, um ein Hintergrundbild in CSS anzugeben:
div {
background: url(data:image/png;base64,iVBORw0K...) no-repeat;
}
Alternativ können auch Daten-URIs innerhalb des src
-Attributes für ein HTML-Element verwendet werden:
<img alt="Logo" src="data:image/png;base64,iVBORw0K..." />
**Eine Beispiel-Verlinkung kann an dieser Stelle nicht bereit gestellt werden, da diese Links verdammt lang sein können und das Limit von der maximalen Länge einer Verlinkung bei Medium überschreiten oder es wird nicht unterstützt!?
Kopiere den folgenden Link und öffne dieses in einem neuen Browser-Fenster: (Microsofts Internet Explorer oder Edge wird nicht unterstützt für dieses Anwendungsszenario.)
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==
Auch wenn diese Zeichenfolge nicht wie ein typischer Link aussieht, da kein http:// oder https:// am Anfang steht, wird dieser Link von den meistens Browsern akzeptiert und verstanden. 🔴
Wenn der Browser Data-URLs unterstützt, sollte ein roter Punkt zu sehen sein.
Alternativ zu einer Daten-URL wie oben, könnte man doch einfach auch direkt auf ein Bild verlinken wie folgt:
<img src="red-dot.png" alt="Red dot" />
Warum sollte man also Daten-URIs verwenden?
Der Hauptvorteil bei der Verwendung von Daten-URIs besteht darin, dass die Anzahl der HTTP-Anfragen reduziert werden können. Jede einzelne Datei, auf die in einem CSS- oder HTML-Code verwiesen wird, erzeugt eine neue HTTP-Anfrage. Durch die Verwendung von Daten-URIs werden die Dateidaten direkt in HTML- oder CSS-Dateien eingebettet, so dass keine HTTP-Anfragen zum Abrufen der Ressource gestellt werden müssen.
Weniger HTTP-Anfragen zu stellen bedeutet letztendlich, dass die Webseite schneller geladen wird, da der Browser nicht so viele Dateien laden muss. Abgesehen vom eigentlichen Herunterladen der Datei benötigt der Browser Zeit, um für jede HTTP-Anforderung eine Verbindung mit dem Server herzustellen. Die Verwendung von Daten-URIs eliminiert diesen Overhead.
Es ist erwähnenswert, dass die Größe der Daten-URI-Zeichenfolge oft um etwa ein Drittel größer ist als die Größe der ursprünglichen Binärdatei. Das bedeutet, dass insgesamt eine größere Datenmenge herunterladen werden muss, die jedoch in einer einzigen Datei mit einer einzigen HTTP-Anforderung komprimiert wird. Das ist in Ordnung, da es meistens schneller ist, eine große Datenmenge über eine einzige Verbindung herunterzuladen, als die gleiche Datenmenge über mehrere Verbindungen (aufgrund des Anforderungs-Overheads, wie bereits vorhin erwähnt).
Verbindung aufbauen - 1. Datei herunterladen - Verbindung abbauen -
Verbindung aufbauen - 2. Datei herunterladen - Verbindung abbauen -
Verbindung aufbauen - X. Datei herunterladen - Verbindung abbauen -
usw.
Nicht Jeder hat eine schnelle Internetverbindung. Einige rasen durch das Internet nach vorne, während andere eher kriechen. Niemand sollte zurück gelassen werden, nur weil die entsprechende Internetgeschwindigkeit nicht zur Verfügung steht!
Vorteile:
HTTP-Anforderungs- und Header-Verkehr ist für eingebettete Daten nicht erforderlich, so dass Daten-URIs immer dann weniger Bandbreite verbrauchen, wenn der Overhead der Codierung des Inline-Inhalts als Daten-URI geringer ist als der HTTP-Overhead. Die erforderliche Base64-Kodierung für ein 600 Byte langes Bild würde beispielsweise in etwa 800 Byte betragen. Wenn also eine HTTP-Anforderung mehr als 200 Byte Overhead erfordert, ist der Daten-URI effizienter.
Bei der Übertragung vieler kleiner Dateien (jeweils weniger als einige Kilobyte) kann dies schneller sein. TCP-Übertragungen neigen dazu, langsam zu beginnen. Wenn für jede Datei eine neue TCP-Verbindung erforderlich ist, wird die Übertragungsgeschwindigkeit eher durch die Hin- und Rücklaufzeit als durch die verfügbare Bandbreite begrenzt. Die Verwendung von HTTP keep-alive verbessert die Situation, kann den Engpass aber möglicherweise nicht vollständig beheben.
Beim Browsen auf einer sicheren HTTPS-Website verlangen Webbrowser in der Regel, dass alle Elemente einer Webseite über sichere Verbindungen heruntergeladen werden, oder der Benutzer wird über eine verminderte Sicherheit aufgrund einer Mischung aus sicheren und unsicheren Elementen benachrichtigt. Auf schlecht konfigurierten Servern haben HTTPS-Anforderungen einen erheblichen Overhead gegenüber gewöhnlichen HTTP-Anforderungen, so dass die Einbettung von Daten in Daten-URIs in diesem Fall die Geschwindigkeit verbessern kann.
Web-Browser sind in der Regel so konfiguriert, dass sie nur eine bestimmte Anzahl (oft zwei) gleichzeitiger HTTP-Verbindungen zu einer Domäne herstellen, so dass Inline-Daten eine Download-Verbindung für andere Inhalte freimachen. Umgebungen mit beschränktem oder eingeschränktem Zugriff auf externe Ressourcen können Inhalte einbetten, wenn es nicht erlaubt oder unpraktisch ist, sie extern zu referenzieren. Beispielsweise könnte ein erweitertes HTML-Bearbeitungsfeld ein eingefügtes Bild akzeptieren und es in eine Daten-URI konvertieren, um die Komplexität externer Ressourcen vor dem Benutzer zu verbergen. Alternativ kann ein Browser bildbasierte Daten aus der Zwischenablage in einen Daten-URI umwandeln und in ein HTML-Editierfeld einfügen.
Es ist möglich, eine Multimedia-Seite als eine einzige Datei zu verwalten. Vorlagen für E-Mail-Nachrichten können z.B. Bilder (für Hintergründe oder Signaturen) enthalten, ohne dass das Bild als “Anhang” erscheint.
Nachteile:
Ein Nachteil der Verwendung von Daten-URIs ist, dass sie vom Browser nicht zwischengespeichert werden. Infolgedessen muss der Browser die Daten-URIs jedes Mal entschlüsseln, wenn die Seite geladen wird, was wertvolle Systemressourcen verbraucht. Mobile Browser können langsam sein, um Daten-URIs zu dekodieren, daher muss die Netzwerkersparnis gegen die zur Dekodierung der Bilder benötigte Zeit abgewogen werden. Wenn auf einer Website viele Daten-URIs verwendet werden, sollten dies in einer Vielzahl von mobilen Browsern getestet werden, um sicherzustellen, dass dies keine negativen Auswirkungen auf die Performance haben.
Daten-URIs werden nicht getrennt von den enthaltenden Dokumenten (z.B. CSS- oder HTML-Dateien) zwischengespeichert, so dass die Daten jedes Mal heruntergeladen werden. Wenn die enthaltenden Dokumente erneut heruntergeladen werden, muss der Inhalt bei jeder Änderung neu kodiert und neu eingebettet werden.
Microsofts Internet Explorer oder Edge bis bieten keine sonderlich gute Implementierung, beziehungsweise Unterstützung. Dies kann jedoch durch die Bereitstellung browserspezifischer Inhalte behoben werden. Internet Explorer 8 begrenzt Daten-URIs auf eine maximale Länge von 32 KB. Wie bereits angesprochen können base64-kodierte Daten-URIs ⅓ größer als das binäre Äquivalent sein. Dieser Overhead wird jedoch auf 2–3% reduziert, wenn der HTTP-Server die Antwort mit gzip komprimiert.
Daten-URIs erschweren allerdings Sicherheitssoftware, Inhalte zu filtern.
Leider lassen sich Data-URIs auch missbrauchen und zwar in Form von Phishing-Angriffen. Ein gelungenes Beispiel zeigt dieses Whitepaper: Phishing by data URI. Dabei wurde eine komplette Webseite als Data-URI eingebettet, welche schädliche XSS-Funktionalität beinhaltet.
Anwendungsfälle:
Eine gute Verwendung von Daten-URIs ist das Herunterladen von Inhalten, die Clientseitig generiert wurden, ohne auf einen serverseitigen Proxy zurückgreifen zu müssen. Hier sind einige Beispiele:
- Speichern der Ausgabe eines Canvas-Elements als Bild,
- Herunterladen einer Tabelle als CSV oder
- Herunterladen der Ausgabe jeder Art von Online-Editor (Text, Zeichnung, CSS-Code …usw.)
Der größte Vorteil: HTTP-Anfragen werden gespeichert/gecached. Abgesehen von der reinen Dokumentengröße ist dies der Faktor Nr. 1 dafür, wie schnell eine Seite geladen wird. Weniger = Besser! Dazu zählt auch die Verwendung von CSS-Sprites und Icon-Fonts, zumindest greifen diese auf das selbe Prinzip zurück.
Browser-Unterstützung für Daten-URIs
Die Browser-Unterstützung für Daten-URIs ist im Allgemeinen sehr gut. Man sollte nur darauf achten, ob IE 5 bis 7 unterstützt werden müssen. Wenn ältere IE-Versionen unterstützt werden müssen, könnten IE-spezifische Stylesheets erstellt werden, das alle Styling-Regeln mit Daten-URIs für solche ausschaltet, die Standarddateipfade verwenden.
Schlussbemerkungen
Die Web-Performance ist etwas, mit dem sich alle Webentwickler mit der Zeit beschäftigen sollten. Man vergisst leicht, dass nicht jedem die gleichen großartigen Breitbandgeschwindigkeiten zur Verfügung steht. Ein großer Teil der Weltbevölkerung kommt gerade online, angeheizt durch die Einführung von Mobiltelefonen, die für den Zugang zum Internet auf langsame Netzwerke angewiesen sind.
Und zu guter Letzt, sollte die Geschwindigkeit noch einmal in Betracht gezogen werden, denn nur weil es für manche Anwendungsfälle deutliche Vorteile bringt, bedeutet das nicht, dass man nur noch Data-URIs zurückgreifen soll! Ein Ausschnitt von Peter McLachlan aus einer Studie zeigt dies noch einmal deutlich:
…when measuring the performance of hundreds of thousands of mobile page views, that loading images using a data URI is on average 6x slower than using a binary source link such as an img tag with an src attribute!
Allerdings muss man hier betonen, dass diese Studie bereits mehr als 7 Jahre alt ist! Und es ist davon auszugehen, dass der Faktor von sechs nicht mehr ganz aktuell sein wird.