Feed e Twitter

Feed RSS Twitter

Busca

Por Lustosa em 17/04/2009 às 11:48

Sempre que queremos colocar uma imagem em uma página, podemos usar a tag img:

<img src="imagem.png" />

ou então, podemos carregá-la como imagem de fundo de um elemento qualquer usando CSS:

.classe { background-image:url(imagem.png); }

Um dos problemas em páginas que possuem muitas imagens é que cada imagem requer a abertura de uma nova conexão HTTP, e com a limitação de 2 conexões por host (é uma restrição dos navegadores que seguem a especificação HTTP), o tempo de carga da página pode acabar crescendo bastante.

A lógica

Uma solução para este problema é ao invés de carregar as imagens externas, colocá-las diretamente dentro da página, seguindo a mesma lógica que já usamos com CSS. Por exemplo, podemos especificar uma folha de estilo externa:

<link rel="stylesheet" type="text/css" href="arquivo.css" />

ou então podemos colocar os estilos inline:

<style type="text/css">
.classe1 { font-color:#f00; }
#id2 { width:200px; }
</style>

Codificando a imagem

Até aí, tudo bem, afinal CSS é texto, e texto entra bem dentro de uma página. Mas como colocar uma imagem dentro de uma página, uma vez que a imagem é binária?
Simples! Primeiro, codificamos a imagem de binário para ASCII usando a codificação base64. Existem várias formas de se fazer isso, e boa parte das linguagens de programação disponibiliza funções para fazer esta codificação. Por exemplo, em PHP, podemos fazer:

<?php
print base64encode(file_get_contents("arquivo.png"));
?>

A saída disso é algo mais ou menos assim:

iVBORw0KGgoAAAANSUhEUgAAAxYAAAAKCAAAAAAMKZcGAAAACXZwQWcAAAMWAAAACgALWq6
YAAAAOklEQVRYw+3TsQ0AIAwEMZT9F4Uh8vTUFCDZM9zV6nyt08kMXOypBnCwBdgCbAG2AF
uALcAWYAt4xQZXmxLmG7UZ3wAAAABJRU5ErkJggg==

Pronto, já temos a representação codificada da imagem.
Para que a saída coubesse na tela, quebrei a saída em 3 linhas. A saída real é toda em uma só linha, mas como veremos adiante, tanto faz, pois podemos usar quebras de linha.

URLs do tipo “data”

Antes de colocarmos a imagem dentro da página, precisamos ver como funcionam as URLs do tipo “data”. A URL segue o seguinte formato:

data:[<tipo MIME>][;charset="<charset>"][;base64],<dados>

onde:

  • tipo MIME é o tipo do arquivo que vamos colocar, no nosso caso, image/png;
  • charset é a codificação utilizada, para o caso de arquivos texto (não usaremos no nosso exemplo).
  • base64 é a codificação utilizada. Se for omitida, o navegador entenderá que estamos usando US-ASCII, e no caso de imagens, não vai dar certo;
  • e por último, dados contém a string com o arquivo codificado (aquela sequencia grande de caracteres ali de cima). A string pode ser quebrada com espaços ou quebras de linha.

Juntando tudo

Pois bem, agora que temos a representação codificada da imagem e já sabemos usar URLs do tipo “data”, podemos colocá-la diretamente na página, usando a própria tag img:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAxYAAAAKCAAAAAAMKZc
GAAAACXZwQWcAAAMWAAAACgALWq6YAAAAOklEQVRYw+3TsQ0AIAwEMZT9F4Uh8vTUFCDZM9zV6n
yt08kMXOypBnCwBdgCbAG2AFuALcAWYAt4xQZXmxLmG7UZ3wAAAABJRU5ErkJggg==" />

Ou então uma regra de CSS, da seguinte forma:

.classe { background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUh
EUgAAAxYAAAAKCAAAAAAMKZcGAAAACXZwQWcAAAMWAAAACgALWq6YAAAAOklEQVRYw+3TsQ0
AIAwEMZT9F4Uh8vTUFCDZM9zV6nyt08kMXOypBnCwBdgCbAG2AFuALcAWYAt4xQZXmxLmG7U
Z3wAAAABJRU5ErkJggg==); }

É claro que usar esta técnica, como quase tudo na vida, tem várias vantagens e desvantagens.

As vantagens

Temos várias vantagens em usar um esquema deste tipo:

  • Suporte na grande maioria dos navegadores modernos: Firefox, Opera, Safari, Konqueror e Chrome;
  • Antes de mais nada, estamos diminuindo o número de requisições HTTP, e consequentemente, evitamos o tráfego associado à requisição (cabeçalhos HTTP);
  • Como a imagem está inline, conseguimos “fugir” do limite de 2 conexões por host, já que estamos evitando a abertura de novas conexões;
  • Para imagens pequenas, temos um ganho real em bytes transferidos, pois embora a imagem codificada em base64 fique maior, estamos evitando de enviar os cabeçalhos HTTP (que somam em média 200 bytes).
  • Conexões seguras (que usam https) só mostram o “cadeado” fechado se todos os elementos externos forem carregados através de https também. E o overhead associado a uma conexão https é bem maior que o de uma conexão http normal. Com a imagem inline, ganhamos mais um pouco.

As desvantagens

Temos várias desvantagens, algumas contornáveis:

  • Internet Explorer até a versão 7 não tem suporte. Só a partir do 8. A forma de se usar para os dois navegadores é usando arquivos CSS separados para cada navegador (ou um pré-processador de CSS que detecte o navegador e dê a saída com o que for suportado);
  • Imagem inline em uma página (usando tag img) não são cacheadas pelo navegador. Se usada dentro do CSS, aí sim teremos o cache em ação, pois o navegador irá cachear o CSS;
  • Uma imagem codificada em base64 tem seu tamanho aumentado em 33%. Para imagens grandes, é uma perda considerável, mas para imagens pequenas (da ordem de 500 bytes), temos um ganho, pois mesmo com o aumento da imagem, estamos evitando o envio dos cabeçalhos, e podemos sair ganhando na soma;
  • Dificuldade de manutenção: se uma imagem é alterada, ela precisa ser recodificada. Existem formas de se automatizar isso.

Um exemplo

A imagem que aparece aqui embaixo está inline, e foi colocada usando uma tag img (a qualidade está baixa pra não ficar muito grande):

Clicando o botão direito na imagem e escolhendo “Exibir imagem” (no Firefox ou em outro navegador que dê suporte), dá pra se ver na barra de endereços a URL usada pra criar a imagem.
E claro, se você não está vendo imagem nenhuma, provavelmente está usando o Internet Explorer. E já passou da hora de passar a usar um navegador decente, que suporta os padrões web, não é?

Artigos relacionados

Arquivado em dicas, programação

Feed RSS para os comentários deste artigo.


Fechado!


Copyright 2009 Ataraxia!   Sinopse