Entwicklertools · Base64-Encoder und -Decoder
Inline-Base64-Bilder in CSS: wann Daten: URIs helfen und wann sie schaden
· Warum es wichtig ist
base64 Leistung
Einbinden eines Bildes als Base64-Daten: URI entfernt eine Anfrage, vergrößert aber die Datei und verhindert das Caching. In diesem Beitrag erfahren Sie, wann sich der Handel lohnt und wann eine separate Datei schneller ist.
Das Stylesheet, das auf Hunderte von Kilobyte angewachsen ist – die Inlining-Gewohnheit eines Teams und wie es sich in den Ladezeiten zeigte
Ein Entwicklungsteam entschied, dass die Einbindung kleiner Symbole als Base64-Daten: URIs in ihrem CSS HTTP-Anfragen reduzieren und die Seitenladegeschwindigkeit verbessern würde. Mit der Zeit, als weitere Symbole hinzugefügt wurden, wuchs das Stylesheet auf 400 Kilobyte.
Das CSS-Bundle, das Stilregeln enthalten sollte, wird jetzt von Bilddaten dominiert. Das Team maß den Ladezeitpunkt und stellte fest, dass die Seite langsamer als vor dem Inlining und nicht schneller war. Das Problem wurde deutlich: Das 400-Kilobyte-Stylesheet wird bei jedem Seitenladen heruntergeladen und pro Seite zwischengespeichert, während bei separaten Dateien für die Symbole eine einzelne Symboldatei zwischengespeichert und auf jeder Seite gemeinsam genutzt würde.
Was für Daten: URI-Inlines und warum es Base64 ist – die Syntax, der Medientyp und der Größennachteil
Das Hinzufügen weiterer Seiten zur Site verschlimmerte das Problem, da jede Seite dasselbe Stylesheet mit all diesen eingebundenen Bildern erneut herunterlädt. In diesem Beitrag wird erklärt, was ein Daten-URI ist, warum er Base64 ist, wie sich Inlining auf Caching und Leistung auswirkt und welche Faustregeln für die Entscheidung gelten, wann sich der Kompromiss lohnt. Eine Daten-URL ist eine Möglichkeit, eine Ressource direkt in eine HTML- oder CSS-Datei einzubetten, anstatt eine Verknüpfung zu einer externen Datei herzustellen. Die Syntax lautet data:mediaType;base64,encoded_bytes.
Der mediaType deklariert, welche Art von Ressource folgt, z. B. image/svg+xml für SVG, image/png für PNG oder text/plain für Text. Das Flag ;base64 gibt an, dass es sich bei der Nutzlast um Base64-codierten und nicht um prozentcodierten Text handelt. Die encoded_bytes sind die eigentlichen Daten. Wenn ein Browser auf eine data:-URL in einer href-, src- oder background-image-Eigenschaft stößt, dekodiert er Base64 und rendert die Ressource inline. Es erfolgt keine HTTP-Anfrage, da die Ressource bereits vorhanden und im übergeordneten Dokument eingebettet ist. Dadurch werden eine oder mehrere HTTP-Anfragen eingespart, was in einer HTTP/1.1-Welt, in der jede Anfrage einen Overhead verursacht, von Bedeutung ist.
Caching und der kritische Pfad – warum inline Bytes mit jeder Seite, die das Stylesheet enthält, erneut heruntergeladen werden
In einer HTTP/2- oder HTTP/3-Welt, in der viele Anfragen über eine Verbindung gemultiplext werden können, sind die Einsparungen geringer. Der Größennachteil der Base64-Codierung ist unmittelbar und erheblich. Ein SVG-Symbol, das 3 Kilobyte groß ist, wenn es als XML-Datei gespeichert wird, wird zu 4 Kilobyte, wenn es Base64-codiert und als Daten eingebettet wird: URI. Die Größenzunahme von 33 % durch die Codierung muss jeder Seite hinzugefügt werden, die das Stylesheet enthält. Wenn das Symbol auf zehn Seiten verwendet wird, wird das Stylesheet zehnmal heruntergeladen, wobei jedes Mal dasselbe 4-Kilobyte große codierte Bild enthalten ist.
Wenn das Symbol eine separate Datei wäre, würde das 3-Kilobyte große Original einmal heruntergeladen und zwischengespeichert und dann aus dem Cache auf allen zehn Seiten verwendet. Bei den meisten Symbolen liegt die wirtschaftliche Entscheidung auf der Hand: Einzelne Dateien sind insgesamt kleiner. Der Inlining-Vorteil kommt nur zum Tragen, wenn ein Symbol auf genau einer Seite oder auf sehr wenigen Seiten verwendet wird und das Symbol für diese Seite wirklich wichtig ist. Ein Favicon, das auf jeder Seite erscheint, ist ein schlechter Kandidat für das Inlining. es ist besser als separate zwischengespeicherte Datei.
Parsing-Kosten auf dem Client – qualitativ beschrieben, wie große Inline-Strings von CSS- und HTML-Parsern verarbeitet werden
Eine einmalige Illustration, die nur auf einer Zielseite verwendet wird, könnte von der Inlining-Funktion profitieren, um eine Anfrage zu speichern. Caching macht die meisten Vorteile des Inlinings von Daten zunichte: URIs in Stylesheets. Ein Stylesheet wird normalerweise tage- oder wochenlang zwischengespeichert. Wenn das Stylesheet heruntergeladen wird, wird jede darin eingebettete Ressource erneut heruntergeladen, auch wenn das Bild im Browser bereits zwischengespeichert ist. Wenn das Stylesheet aktualisiert wird, müssen alle eingebundenen Daten erneut validiert oder erneut heruntergeladen werden, auch wenn nur eine CSS-Regel geändert wurde.
Dies führt zu einer Aufblähung: Änderungen an Farben oder Abständen lösen einen vollständigen erneuten Download des Stylesheets aus, einschließlich Kilobytes an Bilddaten, die sich nicht geändert haben. Eine separate Bilddatei kann unabhängig mit ihren eigenen Ablaufheadern zwischengespeichert, separat aktualisiert und über Stylesheets und Seiten hinweg wiederverwendet werden. Der Browser-Cache ist weitaus effizienter, wenn es sich bei den Ressourcen um separate Dateien handelt, als wenn sie in größere Dokumente eingebettet sind. Die Parsing- und Rendering-Kosten erhöhen sich, wenn große Base64-Strings in Stylesheets eingebettet werden. Ein CSS-Parser muss das gesamte Stylesheet lesen, bevor er Regeln anwendet.
Arbeitsbeispiel: Einbetten eines kleinen SVG-Symbols als Text – Einfügen des Markups in den Encoder und Zusammenstellen der Daten: URI von Hand
Ein 400-Kilobyte großes Stylesheet mit integriertem Base64 besteht aus 400 Kilobyte Text, der analysiert werden muss, bevor Regeln angewendet werden können. Ein HTML-Parser, der eine Seite mit einer großen Datenmenge rendert: Der URI in einem Stilattribut oder einer Hintergrundbildeigenschaft muss Base64 dekodieren und das Bild erstellen, bevor das Element gerendert werden kann. Für einfache SVG-Symbole ist dies trivial. Bei komplexeren Bildern oder größeren Symbolen erfolgt die Dekodierung und das Rendering im Hauptthread, was möglicherweise die Interaktivität blockiert. Die qualitativen Kosten sind real, aber ohne Profilerstellung schwer zu messen.
Wenn das eingebundene Bild größer als ein paar Kilobyte ist, sind separate Dateien in der Regel schneller. Ein ausgearbeitetes Beispiel zeigt den genauen Kompromiss. Nehmen Sie ein einfaches SVG-Pfeilsymbol, 1.2 Kilobyte von XML. Base64-codiert wird es zu 1600 Zeichen oder etwa 1.6 Kilobyte mit dem URL-Präfix data:. Eine separate CSS-Regel mit Hintergrundbild: url(/icons/arrow.svg) fügt dem Stylesheet möglicherweise 40 Bytes hinzu. Die Symboldatei wird einmal heruntergeladen, zwischengespeichert und wiederverwendet. Inlining spart eine HTTP-Anfrage für dieses eine Symbol, fügt aber jedem Stylesheet-Ladevorgang 1.6 Kilobyte hinzu.
Faustregeln, die Bestand haben – winzige, kritische Einweg-Assets inline; alles andere als Datei
Wenn das Stylesheet 50 Kilobyte groß ist und auf 20 Seiten geteilt wird, erhöht das Inlining dieses Symbols den Gesamtdownload um 32 Kilobyte pro Website-Besuch. Die dadurch eingesparte HTTP-Anfrage beträgt höchstens ein paar hundert Byte Overhead. Die Anfrage wird auch automatisch in HTTP/2, gemultiplext, wodurch der Overhead-Unterschied eliminiert wird. Der Inlining-Handel verliert erheblich, es sei denn, das Stylesheet ist winzig, das Symbol riesig oder das Symbol erscheint auf genau einer Seite und nirgendwo sonst. Faustregeln, die einer genauen Prüfung standhalten, sind begrenzt und spezifisch.
Winzige, kritische Einweg-Assets können integriert werden. Ein 200-Byte großer SVG-Pfeil, der nur auf einer ungewöhnlichen Seite erscheint, kann eingebunden werden, um den Anforderungsaufwand zu sparen. Alles andere sollte getrennt sein. Die Logik des Rendering-Pfads ist von entscheidender Bedeutung: Wenn ein Symbol sofort sichtbar sein muss und jede Millisekunde Ladezeit eine Konvertierung kostet, könnte Inlining von Vorteil sein. Für typische Seiten mit typischen Symbolen sind separate Dateien fast immer besser. Testen Sie beide Ansätze mit Ihren tatsächlichen Assets und messen Sie die Seitenauslastung, die Cache-Trefferraten und den Anfrage-Wasserfall.
Was dies nicht abdeckt – HTTP/2 und HTTP/3 Multiplexing-Details und Bildformatkomprimierung
Gehen Sie nicht davon aus, dass Inlining eine Optimierung ohne Messung ist. Der einfachste Weg, ein aufgeblähtes Stylesheet zu erhalten, besteht darin, inkrementell zu inline, ohne zu messen, ob jede Hinzufügung tatsächlich schneller ist. Der Base64-Encoder und -Decoder hilft Ihnen, diese Entscheidung zu treffen, bevor Sie sich für Inlining entscheiden. Fügen Sie Ihr SVG-Markup oder eine andere Symbolquelle als Text in das Tool ein. Klicken Sie auf „Kodieren“ und legen Sie die Optionen zum Generieren eines Daten-URI fest. Das Tool zeigt Ihnen die genaue Länge der Daten an: URL. Vergleichen Sie das mit der Größe einer separaten CSS-Regel und der Asset-Datei selbst.
Berechnen Sie, wie viele Seiten das Stylesheet gemeinsam nutzen müssten, um beim Inlining im Vergleich zu separaten Dateien ausgeglichen zu sein. Stellen Sie den Daten-URI zusammen und testen Sie ihn in einer tatsächlichen HTML-Seite, bevor Sie ihn in das Stylesheet übernehmen. Wenn der URI länger als ein paar hundert Zeichen ist, sind die Kosten für die Einbettung wahrscheinlich größer als der Nutzen, der durch das Speichern einer Anfrage entsteht. Testen Sie mit dem Tool Ihre tatsächlichen Symbole und Assets und messen Sie dann die Auswirkungen auf Ihre tatsächlichen Seitenlademetriken vor und nach dem Inlining.
Takeaway: Sparsam inline und messen – wie Sie mit dem Base64-Encoder und -Decoder SVG-Markup kodieren und die genaue Größe sehen können, bevor Sie es festschreiben
Der performante Ansatz besteht darin, beim Inlining selektiv vorzugehen. Symbole, die auf jeder Seite oder auf mehreren Seiten verwendet werden, sind separate zwischengespeicherte Dateien. Symbole, die auf genau einer Seite verwendet werden oder für den ersten Malvorgang wirklich wichtig sind, können eingebunden werden. Messen Sie den Kompromiss für Ihre tatsächlichen Assets und Seiten, anstatt allgemeinen Ratschlägen zu folgen. Verwenden Sie den Base64-Encoder und -Decoder, um die genaue Größe eines eingebetteten Assets anzuzeigen, bevor Sie es einem Stylesheet hinzufügen. Der Größennachteil ist real und vervielfacht sich bei jedem Seitenaufruf.
Caching und Request-Multiplexing haben den ursprünglichen Vorteil des Inlinings an Bedeutung verloren. Bei den meisten modernen Anwendungen überwiegen kleinere Stylesheets und eine bessere Cache-Effizienz aus separaten Dateien den Anforderungsaufwand. Gehen Sie sparsam vor, messen Sie das Ergebnis und vertrauen Sie der Messung über der Intuition.