Incorporare i dati delle immagini di sfondo nei CSS come Base64 è una buona o cattiva pratica?


475

Stavo guardando la fonte di un utente di greasemonkey e ho notato quanto segue nei loro css:

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

Posso apprezzare che uno script greasemonkey vorrebbe raggruppare tutto ciò che può all'interno del sorgente anziché ospitarlo su un server, è abbastanza ovvio. Ma dal momento che non avevo mai visto questa tecnica in precedenza, ho considerato il suo utilizzo e sembra attraente per una serie di motivi:

  1. Ridurrà la quantità di richieste HTTP al caricamento della pagina, migliorando così le prestazioni
  2. Se nessun CDN, ridurrà la quantità di traffico generato attraverso i cookie inviati insieme alle immagini
  3. I file CSS possono essere memorizzati nella cache
  4. I file CSS possono essere GZIPPED

Considerando che IE6 (ad esempio) ha problemi con la cache per le immagini di sfondo, sembra che non sia la peggiore idea ...

Quindi, è una pratica buona o cattiva, perché non lo usi e quali strumenti useresti per codificare base64 le immagini?

aggiornamento - risultati dei test

Bello, ma sarà leggermente meno utile per immagini più piccole, immagino.

AGGIORNAMENTO: Bryan McQuade, un ingegnere informatico di Google, che lavora su PageSpeed, ha espresso a ChromeDevSummit 2013 che i dati: l'uris nei CSS è considerato un anti-pattern di blocco del rendering per fornire CSS critici / minimi durante il suo discorso #perfmatters: Instant mobile web apps. Vedi http://developer.chrome.com/devsummit/sessions e tienilo a mente - slide reale


Alcuni test vengono eseguiti? Sarebbe interessante quanto la compressione possa compensare il fatto che base64 la codifica.
Dykam,

pubblicato i risultati del test, disponibile anche sul mio blog fragged.org/…
Dimitar Christoff

5
Buona domanda. Volevo solo aggiungere che non funziona per IE7 e inferiori. Ma c'è qualche soluzione. Ecco un bell'articolo a riguardo jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF

2
Aggiunta di più PRO:limiti di cache sui dispositivi cellulari ... CON:alcune immagini dovrebbero essere trattate come contenuto piuttosto che come una semplice presentazione e quindi si adattano meglio ai tag HTML IMG rispetto alle immagini di sfondo CSS.
one.beat.consumer

1
@DimitarChristoff: sono stato un fan di incorporare piccole icone con base64 a causa della sua relativa facilità (se confrontato con lo sprite aggressivo) ed ero felice di accettare le dimensioni generali. Grazie per aver sottolineato che non è sempre il caso (ad esempio, l'incorporamento base64 con gzip potrebbe essere migliore anche in termini di dimensione dell'asset assoluto)
ov

Risposte:


166

Non è una buona idea quando si desidera che le immagini e le informazioni di stile vengano memorizzate nella cache separatamente. Inoltre, se codifichi un'immagine di grandi dimensioni o un numero significativo di immagini nel tuo file css, il download del file in uscita dal tuo sito senza le informazioni sullo stile richiederà più tempo dal browser, fino al completamento del download. Per piccole immagini che non intendi cambiare spesso, se mai è una buona soluzione.

per quanto riguarda la generazione della codifica base64:


less ha una funzione data-uri che incorporerà
Luke Page

è una buona idea se si desidera avere una protezione minima per quelle immagini in modo che non vengano * memorizzate nella cache o potrebbero essere scaricate facendo clic con il tasto destro del mouse -> salva
vsync

"Non è una buona idea quando si desidera che le immagini e le informazioni di stile vengano memorizzate nella cache separatamente": non c'è nulla che impedisca di avere tutte le immagini in un file .css separato.
magritte,

La mia pratica e i test non confermano la tua affermazione. Scusate.
TomeeNS,

55

Questa risposta non è aggiornata e non deve essere utilizzata.

1) La latenza media è molto più veloce sui dispositivi mobili nel 2017. https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

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

Gli "URI dei dati" dovrebbero essere sicuramente considerati per i siti mobili. L'accesso HTTP su reti cellulari ha una latenza maggiore per richiesta / risposta. Quindi ci sono alcuni casi d'uso in cui l'inceppamento delle immagini come dati in modelli CSS o HTML potrebbe essere utile su app Web mobili. Dovresti misurare l'utilizzo caso per caso - non sto sostenendo che gli URI dei dati debbano essere usati ovunque in un'app Web mobile.

Si noti che i browser per dispositivi mobili hanno limitazioni sulla dimensione totale dei file che possono essere memorizzati nella cache. I limiti per iOS 3.2 erano piuttosto bassi (25 KB per file), ma stanno aumentando (100 KB) per le versioni più recenti di Mobile Safari. Quindi assicurati di tenere d'occhio la dimensione totale del file quando includi gli URI dei dati.

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


23

Se fai riferimento a quell'immagine solo una volta, non vedo alcun problema a incorporarla nel tuo file CSS. Ma una volta che usi più di un'immagine o devi fare riferimento più volte nel tuo CSS, potresti prendere in considerazione l'uso di una singola mappa di immagini, invece puoi ritagliare le tue singole immagini da (vedi CSS Sprites ).


16
Significa solo che dovresti avere una classe CSS su un elemento per fare riferimento all'immagine di sfondo e un'altra classe CSS per fare riferimento agli offset in quell'immagine da usare per quell'elemento.
Duncan Beevers,

4
non dovresti avere classi sugli elementi che descrivono come viene presentato il materiale - quelle classi dovrebbero essere ben denominate e semantiche (questo non è sempre possibile, ma è bene sparare per) Se più elementi usano la stessa immagine e vorresti codifica quell'immagine nel CSS, lascia semplicemente l'immagine fuori dalle dichiarazioni e usa una regola CSS successiva per dichiarare e incorporare l'immagine per più selettori / classi.
Adam Tolley,

1
Se stai scattando per le classi semantiche e desideri anche i dati dell'immagine solo una volta, puoi avere uno stile separato che elenca tutti i selettori pertinenti e quindi gli offset definiti in stili per selettore. Naturalmente, per un'immagine molto piccola in molti punti, l'elenco dei selettori potrebbe essere più grande dei dati ...
Leo

Per evitare più classi e specificare un foglio sprite solo una volta, è possibile utilizzare un selettore di attributi:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro,

21

Una delle cose che suggerirei è di avere due fogli di stile separati: uno con le tue definizioni di stile regolari e un altro che contiene le tue immagini nella codifica base64.

Ovviamente devi includere il foglio di stile di base prima del foglio di stile dell'immagine.

In questo modo ti assicurerai che il tuo normale foglio di stile viene scaricato e applicato il più presto possibile al documento, ma allo stesso tempo approfitti delle ridotte richieste HTTP e di altri vantaggi offerti dall'uris dei dati.


1
Mi piace questo in teoria. Qualcuno può pensare a qualche argomento contro?
Rob

Stavo solo cercando su Google questo per scoprire se è una buona idea ed è venuto qui. Nel mio caso le immagini sono tutte solo cose dell'interfaccia utente e stavo pensando che sarebbe stata una buona idea. Non sono sicuro che sia meglio dell'utilizzo di sprite CSS ma ritengo sia più facile gestirlo se si apportano modifiche in futuro. Ti piacerebbe sapere se qualcuno ha qualcosa contro questo?
Craig,

20

Base64 aggiunge circa il 10% alla dimensione dell'immagine dopo GZipping, ma questo supera i vantaggi quando si tratta di dispositivi mobili. Dal momento che c'è una tendenza generale con il web design reattivo, è altamente raccomandato.

W3C raccomanda anche questo approccio per dispositivi mobili e se si utilizza la pipeline di risorse in rotaie, questa è una funzionalità predefinita durante la compressione del CSS

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


buon punto per quanto riguarda mobile / reattivo anche se non sono sicuro del 10%, da dove prendi quei dati?
Dimitar Christoff,

3
Questo è corretto. La cosa più lenta in qualsiasi dispositivo mobile è l'apertura / chiusura delle connessioni http. Si consiglia di minimizzarli.
Rafael Sanches,

nonostante i risultati di W3, in alcuni test ho fatto aumentare la dimensione delle immagini del 25% circa :(
Fabrizio Calderan,

2
Immagino che possa aumentare fino al 33% se è impossibile comprimerlo.
Léon Pelletier,

1
sui dispositivi mobili il 10% è nulla rispetto alla creazione di connessioni http
Rafael Sanches,

4

Non sono d'accordo con la raccomandazione di creare file CSS separati per immagini non editoriali.

Supponendo che le immagini siano per scopi di interfaccia utente, è lo stile del livello di presentazione e, come detto sopra, se stai eseguendo l'interfaccia utente per dispositivi mobili è sicuramente una buona idea mantenere tutto lo stile in un singolo file in modo che possa essere memorizzato nella cache una volta.


3

Nel mio caso mi consente di applicare un foglio di stile CSS senza preoccuparmi di copiare le immagini associate, poiché sono già incorporate all'interno.


3

Ho provato a creare un concetto online di strumento di analisi CSS / HTML:

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

Può:

  • Scarica e analizza i file HTML / CSS, estrae gli elementi href / src / url
  • Rileva i dati di compressione (gzip) e dimensioni sull'URL
  • Confronta le dimensioni dei dati originali, le dimensioni dei dati base64 e le dimensioni dei dati base64 compressi con gzip
  • Convertire l'URL (immagine, font, css, ...) in uno schema URI di dati base64.
  • Contare il numero di richieste che possono essere risparmiate dagli URI dei dati

Commenti / suggerimenti sono benvenuti.

Antonin


3

Puoi codificarlo in PHP :)

<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);
?>

fonte



0

Grazie per le informazioni qui. Sto trovando questo incorporamento utile e in particolare per i dispositivi mobili, specialmente con il file css delle immagini incorporate che viene memorizzato nella cache.

Per rendere la vita più semplice, poiché i miei editor di file non gestiscono nativamente questo, ho creato un paio di semplici script per il lavoro di modifica di laptop / desktop, condividili qui nel caso in cui siano utili a qualcun altro. Mi sono bloccato con php in quanto gestisce queste cose direttamente e molto bene.

Sotto Windows 8.1 dire ---

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

... lì come amministratore puoi stabilire un collegamento a un file batch nel tuo percorso. Quel file batch chiamerà uno script php (cli).

È quindi possibile fare clic con il pulsante destro del mouse su un'immagine in Esplora file e inviare al file batch.

Ok Richiedi una richiesta di avvio e attendi la chiusura delle finestre della shell dei comandi nere.

Quindi semplicemente incolla il risultato dagli appunti nel tuo editor di testo ...

<img src="|">

o

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

Di seguito dovrebbe essere adattabile per altri sistemi operativi.

File batch ...

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

E con php.exe nel tuo percorso, che chiama uno script php (cli) ...

<?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));

?>

0

Per quanto ho studiato,

Usa: 1. Quando stai usando uno svrite sprite. 2. Quando le immagini sono di dimensioni inferiori (max 200 mb).

Non usare: 1. Quando si hanno immagini più grandi. 2. Icone come svg. Dato che sono già buoni e compressi dopo la compressione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.