Bhinish Dhiman
Como converter imagem para base64 (data URI), e quando não fazer isso
Traduzido do original em inglês. Ler o original
Solte o arquivo no conversor de data URI, veja o tamanho em Inlined e copie o trecho Data URI, CSS ou HTML. O base64 escreve cada 3 bytes como 4 caracteres, então o arquivo cresce um terço antes mesmo de entrar o prefixo data:. Embuta só arquivos pequenos: a ferramenta aprova até 4 096 bytes e, acima disso, recomenda uma referência normal ao arquivo, porque uma cópia embutida é baixada de novo com cada documento ou folha de estilo que a contém.
Transformar um arquivo em data URI sempre dá certo. Esse é justamente o problema: nada na conversão avisa que colar uma foto de 200 KB numa folha de estilo acabou de deixar mais lenta cada página que a carrega. A codificação leva segundos. A decisão de usar ou não é a parte que vale acertar.
Dois termos antes de tudo
Um data URI é um URI que carrega os bytes de um arquivo dentro de si, em vez de apontar para um arquivo em outro lugar. Ele é escrito como data:, o tipo MIME do arquivo, ;base64, e depois os bytes codificados, então um PNG começa com data:image/png;base64,.
Base64 é a codificação que torna dados binários seguros para entrar num texto. Ela pega o arquivo de três em três bytes, divide esses 24 bits em quatro grupos de 6 e escreve cada grupo como um caractere de um alfabeto de 64 (2⁶ = 64). Entram três bytes, saem quatro caracteres, seja qual for o conteúdo.
Convertendo o arquivo
- Abra o conversor de data URI e pressione “Choose a file” (escolher um arquivo), ou solte o arquivo em qualquer lugar da página. Ele aceita qualquer coisa: imagens, SVG, fontes. Código SVG colado fora de uma caixa de texto também funciona, e “Try a sample” (experimentar um exemplo) carrega um ícone pequeno.
- Leia os três números que aparecem: “File” (o original), “Inlined” (o data URI completo, com o prefixo) e “Overhead” (a diferença, em porcentagem).
- Leia a linha abaixo deles. Ela diz “Reasonable to inline.” (pode embutir) ou “Use a normal file reference instead.” (use uma referência normal ao arquivo), seguida dos motivos.
- Copie uma das três caixas pelo link de cópia: “Data URI” (a string pura), “CSS” (uma declaração
background-imagecom o URI entre aspas, já que o base64 pode conter uma barra) ou “HTML” (uma tag<img>para imagens, um link de download para o resto). Você também pode escolher o trecho em “Copy as” (copiar como) e copiá-lo com o botão grande embaixo, ou baixá-lo como arquivo .txt pela barra de baixo.
O trecho HTML escreve alt="", o que diz aos leitores de tela que a imagem é decorativa. Se a imagem tem significado, troque isso por uma descrição antes de colar.
Para onde vai o terço a mais
A proporção 4:3 é fixa, então o base64 de qualquer arquivo é previsível: quatro caracteres para cada três bytes, arredondando para cima até um grupo inteiro de quatro. O número “Inlined” da ferramenta também conta o prefixo, e é por isso que o overhead aparece cerca de um ponto acima de 33% em arquivos pequenos: data:image/png;base64, sozinho tem 22 caracteres.
| Arquivo | Bytes | Só o base64 | Data URI completo | Overhead exibido | O que a ferramenta diz |
|---|---|---|---|---|---|
| Ícone PNG | 3 072 | 4 096 | 4 118 | +34% | Reasonable to inline |
| Ícone SVG | 3 072 | 4 096 | 4 122 | +34% | Reasonable to inline |
| PNG, um byte acima do limite | 4 097 | 5 464 | 5 486 | +34% | Use a normal file reference instead |
| Foto JPEG | 204 800 | 273 068 | 273 091 | +33% | Use a normal file reference instead, com três motivos |
Cada linha é aritmética: 4 × ⌈3 072 ÷ 3⌉ = 4,096, e 4 096 + 22 = 4 118. O prefixo do SVG, data:image/svg+xml;base64,, tem 26 caracteres; o do JPEG, 23.
A compressão do servidor recupera parte desse terço durante a transferência, mas menos do que você esperaria, porque o base64 embaralha os padrões de bytes repetidos de que um compressor depende.
O limite de 4 096 bytes, e o que custa ultrapassá-lo
O veredito é decidido pelo tamanho do arquivo original. Até 4 096 bytes, a ferramenta aprova embutir: uma requisição a menos, nada para gerenciar em cache. Com 4 097 bytes ela passa para “Use a normal file reference instead”, e os motivos se acumulam conforme o arquivo cresce.
- Cache, para todo arquivo acima do limite. Um arquivo externo é baixado uma vez e reaproveitado em todas as páginas. Um arquivo embutido viaja dentro do arquivo que o contém, então é baixado de novo com cada documento ou folha de estilo que o incorpora.
- Imagens responsivas, para imagens acima do limite. Um data URI não tem uma URL sobre a qual o navegador possa negociar, então você perde o
srcset, o carregamento lento (lazy loading) e qualquer otimização de imagem que uma CDN aplicaria. Uma fonte acima do limite recebe o aviso de cache, mas não este. - Bloqueio de renderização, acima de 32 768 bytes (8 × 4 096). Numa folha de estilo, o base64 precisa chegar antes que a página possa ser renderizada, e uma única edição de CSS sem relação nenhuma invalida a cópia em cache de todos os recursos embutidos junto.
A foto de 200 KB da tabela esbarra nos três. A própria frase da ferramenta para ela diz “At 200 KB this becomes roughly 267 KB inlined” (com 200 KB, isso vira cerca de 267 KB embutido), e esses 267 KB vão junto com a folha de estilo em toda visita em que ela ainda não estiver em cache.
Quando um data URI é a escolha certa
Pequeno, usado num só lugar e autossuficiente: um único ícone dentro de um bloco de estilo inline é o caso clássico. Deixe o arquivo o menor possível antes de codificá-lo, porque cada 3 bytes economizados tiram 4 caracteres do resultado. Um SVG pode passar antes pelo otimizador de SVG, e um PNG pelo compressor de imagens, que o regrava sem mudar um pixel.
| O conversor de data URI | O comando base64 |
Um codificador online simples | |
|---|---|---|---|
| O arquivo sai do seu computador | Não | Não | Depende do serviço |
Prefixo data: e tipo MIME |
Escritos para você | Você acrescenta | Varia |
| Tamanho exibido com o prefixo | Sim, como “Inlined” | Não | Varia |
| Recomendação sobre embutir ou não | Sim, com motivos | Não | Raramente |
Outras formas de fazer isso
Na linha de comando, a ferramenta base64 faz a codificação:
base64 -i icon.png # macOS
base64 -w0 icon.png # GNU/Linux
A saída é a string base64 pura. Para usá-la como data URI, coloque data:image/png;base64, na frente, com o tipo MIME correspondente ao arquivo; se o tipo estiver errado, o arquivo pode não ser exibido: os navegadores deduzem alguns tipos de imagem pelos bytes, mas um SVG precisa estar rotulado como image/svg+xml.
Conferindo que nada foi enviado
O arquivo é lido na memória do seu navegador e codificado ali, o que também significa que não há limite de tamanho além da sua própria memória. Para confirmar, abra as ferramentas de desenvolvedor do navegador na aba Network (rede) antes de soltar o arquivo: a codificação não gera nenhuma requisição.
Faça a conversão, e a decisão, no conversor de data URI. Se o veredito for não embutir, reduzir o arquivo com o compressor de imagens e servi-lo normalmente costuma ser a melhor troca.