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.

URL para Trackback.


Nenhum comentário.


Comentar




Copyright 2009 Ataraxia!   Sinopse