Ist das Einbetten von Hintergrundbilddaten in CSS als Base64 eine gute oder schlechte Praxis?

475

Ich habe mir die Quelle eines Greasemonkey-Benutzer-Skripts angesehen und in ihrem CSS Folgendes festgestellt:

.even { background: #fff url(data:image/gif;base64,R0lGODlhBgASALMAAOfn5+rq6uvr6+zs7O7u7vHx8fPz8/b29vj4+P39/f///wAAAAAAAAAAAAAAAAAAACwAAAAABgASAAAIMAAVCBxIsKDBgwgTDkzAsKGAhxARSJx4oKJFAxgzFtjIkYDHjwNCigxAsiSAkygDAgA7) repeat-x bottom}

Ich kann verstehen, dass ein Greasemonkey-Skript alles, was es kann, in der Quelle bündeln möchte, anstatt es auf einem Server zu hosten, das ist offensichtlich genug. Da ich diese Technik zuvor noch nicht gesehen hatte, habe ich über ihre Verwendung nachgedacht und sie scheint aus mehreren Gründen ansprechend zu sein:

  1. Dadurch wird die Anzahl der HTTP-Anforderungen beim Laden der Seite verringert und somit die Leistung verbessert
  2. Wenn kein CDN vorhanden ist, wird der Datenverkehr reduziert, der durch Cookies generiert wird, die neben Bildern gesendet werden
  3. CSS-Dateien können zwischengespeichert werden
  4. CSS-Dateien können GZIPPED sein

Wenn man bedenkt, dass IE6 (zum Beispiel) Probleme mit dem Cache für Hintergrundbilder hat, scheint dies nicht die schlechteste Idee zu sein ...

Also, ist dies eine gute oder schlechte Praxis, warum würden Sie es nicht verwenden und welche Tools würden Sie verwenden, um die Bilder mit base64 zu codieren?

Update - Testergebnisse

Schön, aber für kleinere Bilder ist es etwas weniger nützlich, denke ich.

UPDATE: Bryan McQuade, ein Softwareentwickler bei Google, der an PageSpeed ​​arbeitet, hat auf der ChromeDevSummit 2013 zum Ausdruck gebracht, dass data: uris in CSS während seines Vortrags als Render-Blocking-Anti-Pattern für die Bereitstellung von kritischem / minimalem CSS angesehen wird #perfmatters: Instant mobile web apps. Siehe http://developer.chrome.com/devsummit/sessions und denken Sie daran - tatsächliche Folie

Dimitar Christoff
quelle
Machen Sie einige Testläufe? Es wäre interessant, inwieweit die Komprimierung die Tatsache kompensieren kann, dass Sie base64 codieren.
Dykam
postete die Ergebnisse des Tests, auch auf meinem Blog fragged.org/…
Dimitar Christoff
5
Gute Frage. Ich wollte nur hinzufügen, dass es für IE7 und darunter nicht funktioniert. Aber es gibt einige Umgehungsmöglichkeiten. Hier ist ein schöner Artikel darüber jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF
2
Hinzufügen von mehr PRO:Cache-Beschränkungen auf Mobilfunkgeräten ... CON:Einige Bilder sollten eher als Inhalt als als einfache Präsentation behandelt werden und eignen sich daher besser für HTML-IMG-Tags als für CSS-Hintergrundbilder.
one.beat.consumer
1
@ DimitarChristoff: Ich war ein Fan von der Einbettung kleiner Symbole in base64, weil es relativ einfach ist (im Vergleich zu aggressivem Spriting), und war froh, die Größe des Overheads zu akzeptieren. Vielen Dank für den Hinweis auf , dass es nicht immer der Fall ist (dh gzipped base64 einbetten kann besser in Bezug auf die absolute Asset - Größe als auch)
ov

Antworten:

166

Es ist keine gute Idee, wenn Ihre Bilder und Stilinformationen separat zwischengespeichert werden sollen. Wenn Sie ein großes Bild oder eine erhebliche Anzahl von Bildern in Ihre CSS-Datei codieren, dauert es länger, bis der Browser die Datei herunterlädt, die Ihre Site ohne Stilinformationen verlässt, bis der Download abgeschlossen ist. Für kleine Bilder, die Sie nicht oft ändern möchten, ist dies eine gute Lösung.

Soweit die base64-Codierung generiert wird:

Kacke eine Birke
quelle
less hatte eine Data-Uri-Funktion, die ein Bild inlineciert. lesscss.org/#reference
Luke Page
Es ist eine gute Idee, wenn Sie einen minimalen Schutz für diese Bilder wünschen, damit sie nicht zwischengespeichert werden oder durch Klicken mit der rechten Maustaste -> Speichern
vsync
"Es ist keine gute Idee, wenn Sie möchten, dass Ihre Bilder und Stilinformationen separat zwischengespeichert werden" - nichts hindert Sie daran, alle Bilder in einer separaten CSS-Datei zu haben.
Magritte
Meine Praxis und meine Tests bestätigen Ihre Aussage nicht. Es tut uns leid.
TomeeNS
55

Diese Antwort ist veraltet und sollte nicht verwendet werden.

1) Die durchschnittliche Latenz ist 2017 auf Mobilgeräten viel schneller. Https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

2) HTTP2-Multiplexe https://http2.github.io/faq/#why-is-http2-multiplexed

"Daten-URIs" sollten auf jeden Fall für mobile Websites berücksichtigt werden. Der HTTP-Zugriff über Mobilfunknetze ist mit einer höheren Latenz pro Anforderung / Antwort verbunden. Es gibt also einige Anwendungsfälle, in denen das Jammen Ihrer Bilder als Daten in CSS- oder HTML-Vorlagen für mobile Webanwendungen von Vorteil sein kann. Sie sollten die Nutzung von Fall zu Fall messen. Ich befürworte nicht, dass Daten-URIs überall in einer mobilen Web-App verwendet werden sollten.

Beachten Sie, dass mobile Browser Einschränkungen hinsichtlich der Gesamtgröße der Dateien haben, die zwischengespeichert werden können. Die Limits für iOS 3.2 waren ziemlich niedrig (25 KB pro Datei), werden jedoch für neuere Versionen von Mobile Safari immer größer (100 KB). Behalten Sie also Ihre gesamte Dateigröße im Auge, wenn Sie Daten-URIs einschließen.

http://www.yuiblog.com/blog/2010/06/28/mobile-browser-cache-limits/

Mike Brittain
quelle
23

Wenn Sie nur einmal auf dieses Bild verweisen, sehe ich kein Problem beim Einbetten in Ihre CSS-Datei. Wenn Sie jedoch mehr als ein Bild verwenden oder es in Ihrem CSS mehrmals referenzieren müssen, können Sie stattdessen eine einzelne Image Map verwenden, aus der Sie dann Ihre einzelnen Bilder zuschneiden können (siehe CSS-Sprites ).

Gumbo
quelle
16
Es bedeutet nur, dass Sie eine CSS-Klasse für ein Element haben sollten, um auf das Hintergrundbild zu verweisen, und eine andere CSS-Klasse, um die Offsets in dieses Bild zu verweisen, die für dieses Element verwendet werden sollen.
Duncan Beevers
4
Sie sollten KEINE Klassen für die Elemente haben, die beschreiben, wie Material präsentiert wird. Diese Klassen sollten gut benannt und semantisch sein (dies ist nicht immer möglich, aber gut zu fotografieren). Wenn mehrere Elemente dasselbe Bild verwenden und Sie möchten Codieren Sie dieses Bild im CSS, lassen Sie das Bild einfach aus den Deklarationen heraus und verwenden Sie eine spätere CSS-Regel, um das Bild für mehrere Selektoren / Klassen zu deklarieren und einzubetten.
Adam Tolley
1
Wenn Sie für semantische Klassen fotografieren und die Bilddaten auch nur einmal verwenden möchten, können Sie einen separaten Stil verwenden, in dem alle relevanten Selektoren und dann in den Auswahlstilen definierten Offsets aufgelistet sind. Natürlich kann für ein sehr kleines Bild an vielen Stellen die
Leo
Um mehrere Klassen zu vermeiden und ein Sprite-Blatt nur einmal anzugeben, können Sie eine Attributauswahl verwenden:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro
21

Eines der Dinge, die ich vorschlagen würde, ist, zwei separate Stylesheets zu haben: eines mit Ihren regulären Stildefinitionen und eines, das Ihre Bilder in Base64-Codierung enthält.

Sie müssen das Basis-Stylesheet natürlich vor dem Bild-Stylesheet einfügen.

Auf diese Weise stellen Sie sicher, dass Ihr reguläres Stylesheet so schnell wie möglich heruntergeladen und auf das Dokument angewendet wird. Gleichzeitig profitieren Sie von reduzierten http-Anfragen und anderen Vorteilen, die Data-Uris Ihnen bieten.

ximi
quelle
1
Ich mag das theoretisch. Kann sich jemand Argumente dagegen vorstellen?
Rob
Ich habe das nur selbst gegoogelt, um herauszufinden, ob es eine gute Idee ist, und bin hierher gekommen. In meinem Fall sind die Bilder nur UI-Inhalte und ich dachte, das wäre eine gute Idee. Ich bin mir nicht sicher, ob es besser ist als die Verwendung von CSS-Sprites, aber ich denke, es ist einfacher zu verwalten, wenn Sie in Zukunft Änderungen vornehmen. Würde gerne wissen, ob jemand etwas dagegen hat?
Craig
20

Base64 erhöht die Bildgröße nach GZipped um etwa 10%, aber das überwiegt die Vorteile, wenn es um mobile Geräte geht. Da es bei Responsive Web Design einen allgemeinen Trend gibt, wird dies dringend empfohlen.

W3C empfiehlt diesen Ansatz auch für Mobilgeräte. Wenn Sie die Asset-Pipeline in Rails verwenden, ist dies eine Standardfunktion beim Komprimieren Ihres CSS

http://www.w3.org/TR/mwabp/#bp-conserve-css-images

Greg
quelle
Guter Punkt für Mobilgeräte / Reaktionszeiten, obwohl ich mir nicht sicher bin, woher die 10% stammen. Woher beziehen Sie diese Daten?
Dimitar Christoff
3
Das ist richtig. Das Langsamste auf einem mobilen Gerät ist das Öffnen / Schließen von http-Verbindungen. Es wird empfohlen, sie zu minimieren.
Rafael Sanches
Trotz w3-Ergebnissen habe ich in einigen Tests die Größe der Bilder um ~ 25% erhöht :(
Fabrizio Calderan
2
Ich denke, es kann bis zu 33% erhöhen, wenn es einfach unmöglich ist, es zu komprimieren.
Léon Pelletier
1
auf dem Handy 10% ist nichts im Vergleich zur Schaffung von http-Verbindungen
Rafael Sanches
4

Ich bin mit der Empfehlung nicht einverstanden, separate CSS-Dateien für nicht redaktionelle Bilder zu erstellen.

Angenommen, die Bilder dienen der Benutzeroberfläche, dann handelt es sich um das Styling der Präsentationsebene. Wie oben erwähnt, ist es auf jeden Fall eine gute Idee, das gesamte Styling in einer einzigen Datei zu speichern, damit es einmal zwischengespeichert werden kann.

tim
quelle
3

In meinem Fall kann ich ein CSS-Stylesheet anwenden, ohne mir Gedanken über das Kopieren der zugehörigen Bilder machen zu müssen, da diese bereits darin eingebettet sind.

Rolf
quelle
3

Ich habe versucht, ein Online-Konzept für das CSS / HTML-Analysetool zu erstellen:

http://www.motobit.com/util/base64/css-images-to-base64.asp

Es kann:

  • Laden Sie HTML / CSS-Dateien herunter und analysieren Sie sie, extrahieren Sie href / src / url-Elemente
  • Ermitteln Sie Komprimierungs- (gzip) und Größendaten in der URL
  • Vergleichen Sie die ursprüngliche Datengröße, die base64-Datengröße und die gezippte base64-Datengröße
  • Konvertieren Sie die URL (Bild, Schriftart, CSS, ...) in ein Base64-Daten-URI-Schema.
  • Zählen Sie die Anzahl der Anforderungen, die von Daten-URIs gespart werden können

Kommentare / Vorschläge sind willkommen.

Antonin

Antonin Foller
quelle
3

Sie können es in PHP codieren :)

<img src="data:image/gif;base64,<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>">

Or display in our dynamic CSS.php file:

background: url("data:image/gif;base64,<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>");

1 That’s sort of a “quick-n-dirty” technique but it works. Here is another encoding method using fopen() instead of file_get_contents():

<?php // convert image to dataURL
$img_source = "feed-icon.gif"; // image path/name
$img_binary = fread(fopen($img_source, "r"), filesize($img_source));
$img_string = base64_encode($img_binary);
?>

Quelle

ucefkh
quelle
2

Für Benutzer von Sublime Text 2 gibt es ein Plugin, das den Base64-Code enthält, mit dem wir die Bilder in den ST laden.

Aufgerufenes Image2base64: https://github.com/tm-minty/sublime-text-2-image2base64

PS: Speichern Sie diese vom Plugin generierte Datei niemals, da sie die Datei überschreiben und zerstören würde.

Daniel Santarriaga
quelle
0

Danke für die Information hier. Ich finde diese Einbettung nützlich und insbesondere für Mobilgeräte, insbesondere wenn die CSS-Datei der eingebetteten Bilder zwischengespeichert wird.

Um das Leben zu erleichtern, habe ich einige einfache Skripte für die Bearbeitung von Laptops / Desktops erstellt, die hier geteilt werden, falls sie für andere Personen von Nutzen sind, da meine Datei-Editoren dies nicht von Haus aus tun. Ich habe mich an PHP gehalten, da es diese Dinge direkt und sehr gut handhabt.

Sagen Sie unter Windows 8.1 ---

C:\Users\`your user name`\AppData\Roaming\Microsoft\Windows\SendTo

... dort können Sie als Administrator eine Verknüpfung zu einer Batchdatei in Ihrem Pfad erstellen. Diese Batch-Datei ruft ein PHP (CLI) -Skript auf.

Sie können dann im Datei-Explorer mit der rechten Maustaste auf ein Bild klicken und an die Batchdatei senden.

Ok Admiinstartor-Anfrage, und warten Sie, bis die schwarzen Befehls-Shell-Fenster geschlossen sind.

Fügen Sie dann einfach das Ergebnis aus der Zwischenablage in Ihren Texteditor ein ...

<img src="|">

oder

 `background-image : url("|")` 

Das Folgende sollte für andere Betriebssysteme anpassbar sein.

Batch-Datei ...

rem @echo 0ff
rem Puts 64 encoded version of a file on clipboard
php c:\utils\php\make64Encode.php %1

Und mit php.exe in Ihrem Pfad ruft das ein PHP (CLI) -Skript auf ...

<?php 

function putClipboard($text){
 // Windows 8.1 workaround ...

  file_put_contents("output.txt", $text);

  exec("  clip < output.txt");

}


// somewhat based on http://perishablepress.com/php-encode-decode-data-urls/
// convert image to dataURL

$img_source = $argv[1]; // image path/name
$img_binary = fread(fopen($img_source, "r"), filesize($img_source));
$img_string = base64_encode($img_binary);

$finfo = finfo_open(FILEINFO_MIME_TYPE); 
$dataType = finfo_file($finfo, $img_source); 


$build = "data:" . $dataType . ";base64," . $img_string; 

putClipboard(trim($build));

?>
PaulANormanNZ
quelle
0

Soweit ich recherchiert habe,

Verwendung: 1. Wenn Sie ein SVG-Sprite verwenden. 2. Wenn Ihre Bilder eine geringere Größe haben (max. 200 MB).

Nicht verwenden: 1. Wenn Sie größere Bilder haben. 2. Symbole als SVGs. Da sie schon gut sind und nach der Komprimierung gezippt werden.

Pooja Esakkimuthu
quelle