A incorporação de dados de imagem de plano de fundo no CSS como base64 é uma boa ou má prática?

475

Eu estava olhando para a fonte de um script de usuário greasemonkey e notei o seguinte em seu css:

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

Compreendo que um script greasemonkey deseje agrupar tudo o que puder na fonte, em vez de hospedá-lo em um servidor, isso é óbvio o suficiente. Mas como não tinha visto essa técnica anteriormente, considerei seu uso e parece atraente por várias razões:

  1. Reduzirá a quantidade de solicitações HTTP no carregamento da página, melhorando o desempenho
  2. Se não houver CDN, reduzirá a quantidade de tráfego gerado pelos cookies enviados juntamente com as imagens
  3. Arquivos CSS podem ser armazenados em cache
  4. Arquivos CSS podem ser GZIPPED

Considerando que o IE6 (por exemplo) tem problemas com o cache de imagens de fundo, parece que essa não é a pior idéia ...

Portanto, essa é uma prática boa ou ruim, por que você não a usa e quais ferramentas você usa para codificar as imagens na base64?

update - resultados dos testes

Bom, mas será um pouco menos útil para imagens menores, eu acho.

ATUALIZAÇÃO: Bryan McQuade, engenheiro de software do Google, que trabalha no PageSpeed, expressou no ChromeDevSummit 2013 que dados: uris em CSS são considerados um anti-padrão de bloqueio de renderização por fornecer CSS crítico / mínimo durante sua palestra #perfmatters: Instant mobile web apps. Consulte http://developer.chrome.com/devsummit/sessions e lembre-se disso - slide real

Dimitar Christoff
fonte
Faz alguns testes? Seria interessante o quanto a compactação pode compensar o fato de você a codificar em base64.
dykam
postou os resultados do teste, também disponível no meu blog fragged.org/…
Dimitar Christoff
5
Boa pergunta. Só queria acrescentar que ele não funciona para o IE7 e abaixo. Mas existem algumas soluções. Aqui está um bom artigo sobre isso jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF
2
Adicionando mais PRO:limites de cache em dispositivos celulares ... CON:algumas imagens devem ser tratadas como conteúdo em vez de simples apresentação e, portanto, são mais adequadas para tags HTML IMG do que imagens de fundo CSS.
one.beat.consumer
1
@DimitarChristoff: Eu sou fã de incorporar pequenos ícones com base64 por causa de sua relativa facilidade (ao comparar com sprites agressivos) e fiquei feliz em aceitar o tamanho da sobrecarga. Obrigado por apontar que nem sempre é o caso (ou seja gzipped base64 incorporar pode ser melhor em termos de volume de ativos absoluta também)
ov

Respostas:

166

Não é uma boa ideia quando você deseja que suas imagens e informações de estilo sejam armazenadas em cache separadamente. Além disso, se você codificar uma imagem grande ou um número significativo de imagens no seu arquivo css, o navegador levará mais tempo para baixar o arquivo deixando o site sem nenhuma informação de estilo até que o download seja concluído. Para imagens pequenas que você não pretende mudar com frequência, se é que é uma boa solução.

na medida em que gera a codificação base64:

cocô um birck
fonte
menos tinha uma função dados-URI que in-line uma imagem lesscss.org/#reference
Luke Page
é uma boa idéia se você quiser ter uma protecção mínima para essas imagens para que elas não * ser armazenado em cache ou pode ser baixado clicando com o botão direito -> save
vsync
"Não é uma boa ideia quando você deseja que suas imagens e informações de estilo sejam armazenadas em cache separadamente" - não há nada para impedir que você tenha todas as imagens em um arquivo .css separado.
magritte
Minha prática e testes não confirmam sua declaração. Desculpa.
TomeeNS
55

Esta resposta está desatualizada e não deve ser usada.

1) A latência média é muito mais rápida no celular em 2017. https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

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

Definitivamente, os "URIs de dados" devem ser considerados para sites para celular. O acesso HTTP através de redes celulares vem com maior latência por solicitação / resposta. Portanto, existem alguns casos de uso em que inserir suas imagens como dados em modelos CSS ou HTML pode ser benéfico em aplicativos da web móveis. Você deve avaliar o uso caso a caso - não estou defendendo que os URIs de dados sejam usados ​​em todos os lugares em um aplicativo da web móvel.

Observe que os navegadores móveis têm limitações no tamanho total dos arquivos que podem ser armazenados em cache. Os limites para o iOS 3.2 eram bastante baixos (25 mil por arquivo), mas estão ficando maiores (100 mil) para as versões mais recentes do Mobile Safari. Portanto, verifique o tamanho total do arquivo ao incluir URIs de dados.

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

Mike Brittain
fonte
23

Se você referenciar essa imagem apenas uma vez, não vejo problema em incorporá-la ao seu arquivo CSS. Porém, depois de usar mais de uma imagem ou precisar fazer referência a ela várias vezes em seu CSS, considere usar um mapa de imagem única. Em seguida, você poderá recortar suas imagens únicas (consulte CSS Sprites ).

quiabo
fonte
16
Significa apenas que você deve ter uma classe css em um elemento para referenciar a imagem de plano de fundo e outra classe css para referenciar os deslocamentos nessa imagem para usar nesse elemento.
Duncan Beevers 01/10/10
4
você NÃO deve ter aulas sobre os elementos que descrevem como o material é apresentado - essas classes devem ser bem nomeadas e semânticas (isso nem sempre é possível, mas é bom de se atirar). Se vários elementos usarem a mesma imagem e você desejar codifique essa imagem no CSS, apenas deixe a imagem fora das declarações e use uma regra css posterior para declarar e incorporar a imagem a vários seletores / classes.
23412 Adam Tolley
1
Se você estiver gravando para aulas semânticas e também quiser os dados da imagem apenas uma vez, poderá ter um estilo separado que lista todos os seletores relevantes e, em seguida, os desvios definidos nos estilos por seletor. Claro que, para uma imagem muito pequena em um monte de lugares, a lista selector pode ser maior do que os dados ...
Leo
Para evitar várias classes e especificar apenas uma planilha de sprite uma vez, você pode usar um seletor de atributos:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro
21

Uma das coisas que eu sugeriria é ter duas folhas de estilo separadas: uma com suas definições de estilo regulares e outra que contém suas imagens na codificação base64.

Você deve incluir a folha de estilo base antes da folha de estilo da imagem, é claro.

Dessa forma, você garantirá que sua folha de estilo regular seja baixada e aplicada o mais rápido possível ao documento, mas, ao mesmo tempo, lucra com solicitações de http reduzidas e outros benefícios que os uris de dados oferecem.

ximi
fonte
1
Eu gosto disso em teoria. Alguém pode pensar em algum argumento contra?
Rob
Eu mesmo estava pesquisando no Google para descobrir se é uma boa ideia e vim aqui. No meu caso, as imagens são apenas coisas da interface do usuário e eu estava pensando que isso seria uma boa idéia. Não tenho certeza se é melhor do que usar sprites de css, mas acho que é mais fácil gerenciar se você fizer alterações no futuro. Gostaria de saber se alguém tem algo contra isso?
20918 Craig
20

O Base64 adiciona cerca de 10% ao tamanho da imagem após o GZipped, mas isso supera os benefícios quando se trata de dispositivos móveis. Como existe uma tendência geral no design responsivo da web, é altamente recomendável.

O W3C também recomenda essa abordagem para dispositivos móveis e, se você usar o pipeline de ativos nos trilhos, esse é um recurso padrão ao compactar seu css

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

Greg
fonte
bom ponto é móvel / responsivo, embora eu não tenha certeza dos 10%, de onde você obtém esses dados?
precisa saber é o seguinte
3
Isto está correto. A coisa mais lenta em qualquer dispositivo móvel é a abertura / fechamento de conexões http. Minimizar eles é recomendado.
Rafael Sanches
apesar dos resultados w3, em algum teste que fiz o tamanho das imagens aumentou em ~ 25% :(
Fabrizio Calderan
2
Eu acho que pode aumentar até 33% se for impossível compactá-lo.
Léon Pelletier
1
no celular de 10% não é nada comparado à criação de conexões HTTP
Rafael Sanches
4

Não concordo com a recomendação de criar arquivos CSS separados para imagens não editoriais.

Supondo que as imagens sejam para fins de interface do usuário, é o estilo da camada de apresentação e, como mencionado acima, se você estiver fazendo UI móvel, é definitivamente uma boa idéia manter todo o estilo em um único arquivo para que possa ser armazenado em cache uma vez.

tim
fonte
3

No meu caso, me permite aplicar uma folha de estilo CSS sem me preocupar em copiar imagens associadas, pois elas já estão incorporadas.

Rolf
fonte
3

Tentei criar um conceito online da ferramenta analisadora de CSS / HTML:

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

Pode:

  • Baixe e analise arquivos HTML / CSS, extraia elementos href / src / url
  • Detectar dados de compactação (gzip) e tamanho no URL
  • Compare o tamanho dos dados originais, o tamanho dos dados base64 e o tamanho dos dados base64 compactados com gzip
  • Converta a URL (imagem, fonte, css, ...) em um esquema de URI de dados base64.
  • Contar o número de solicitações que podem ser poupadas pelos URIs de dados

Comentários / sugestões são bem-vindos.

Antonin

Antonin Foller
fonte
3

Você pode codificá-lo em 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

ucefkh
fonte
2

Trazendo um pouco para os usuários do Sublime Text 2, existe um plugin que fornece o código base64 para carregar as imagens no ST.

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

PS: Nunca salve este arquivo gerado pelo plug-in, porque ele sobrescreveria e destruiria.

Daniel Santarriaga
fonte
0

Obrigado pela informação aqui. Estou achando essa incorporação útil e particularmente para dispositivos móveis, especialmente com o arquivo css das imagens incorporadas sendo armazenado em cache.

Para ajudar a tornar a vida mais fácil, como meus editores de arquivos não lidam com isso nativamente, criei alguns scripts simples para a edição de laptops / desktops, compartilhe aqui caso eles sejam úteis a qualquer outra pessoa. Eu fiquei com o php, pois ele está lidando com essas coisas diretamente e muito bem.

No Windows 8.1, diga ---

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

... como administrador, você pode estabelecer um atalho para um arquivo em lotes no seu caminho. Esse arquivo em lotes chamará um script php (cli).

Você pode clicar com o botão direito do mouse em uma imagem no explorador de arquivos e em EnviarPara o lote.

Ok, solicite o Admiinstartor e aguarde o fechamento das janelas pretas do shell de comando.

Em seguida, basta colar o resultado da área de transferência no seu editor de texto ...

<img src="|">

ou

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

A seguir deve ser adaptável para outro sistema operacional.

Arquivo em lote ...

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

E com o php.exe no seu caminho, isso chama um 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));

?>
PaulANormanNZ
fonte
0

Tanto quanto eu pesquisei,

Uso: 1. Quando você estiver usando um sprite svg. 2. Quando suas imagens são de tamanho menor (máx. 200mb).

Não use: 1. Quando você tem imagens maiores. 2. Ícones como svg. Como eles já estão bons e compactados após a compactação.

Pooja Esakkimuthu
fonte