Uma breve história das imagens na Web

Não importa em que ponto você está aprendendo a criar e desenvolver para a Web, o elemento <img> precisa de pouca introdução. Lançado no Netscape ("Mosaic", na época) em 1993 e adicionado à especificação HTML em 1995, o <img> desempenha um papel simples, mas poderoso, dentro da plataforma da Web. O desenvolvedor adiciona um arquivo de imagem de "origem" com o atributo src e fornece uma alternativa de texto com o atributo alt caso a imagem não possa ser renderizada ou as tecnologias assistivas solicitem uma alternativa. A partir daí, o navegador tem apenas uma tarefa: extrair os dados da imagem e renderizá-los o mais rápido possível.

Durante grande parte da história do desenvolvimento da Web, trabalhar com imagens não foi muito mais complicado do que isso. E, apesar da complexidade da Web moderna, as noções básicas de trabalhar com imagens não mudaram: use um formato de imagem compatível com a Web para fins de compatibilidade, compressão sensata para economizar largura de banda e dimensões adequadas ao espaço que a imagem vai ocupar no layout da página.

O uso de layouts de largura fixa, como fizemos quando pensávamos mais na experiência dos usuários com a Web, tornava esse processo simples. Foi muito fácil definir o tamanho da origem da imagem. Para uma imagem que ocupava um espaço de 500 pixels de largura e 300 pixels de altura, era um caso de especificar uma imagem de origem com o mesmo tamanho.

Imagens em um layout responsivo

Juntamente com um layout flexível e o uso de consultas de mídia CSS, "imagens e mídia flexíveis" são uma das três facetas que definem o Web design responsivo. Para tornar uma imagem flexível, os desenvolvedores começaram a usar CSS para definir max-width: 100% na imagem (ou em todas as imagens, em todo o site) para instruir o mecanismo de renderização do navegador a evitar que uma imagem ultrapasse o contêiner pai por meio da redução. Visualmente, isso funciona perfeitamente. A redução de uma imagem de raster é visualmente integrada. Com uma ou duas linhas de CSS, uma imagem reduzida sempre parecerá ter especificado uma origem de imagem para ser exibida nesse tamanho. Quando os mecanismos de renderização recebem mais dados de imagem do que o necessário para o espaço que a imagem ocupa em um layout, eles podem tomar decisões informadas sobre como renderizar a imagem reduzida sem introduzir artefatos visuais ou desfoque.

Normalmente, não é recomendado aumentar uma imagem, ou seja, renderizar o <img> em um tamanho maior que o intrínseco da imagem de origem. A imagem exibida ficaria desfocada e granulada.

Usar img { max-width: 100% } significa que, à medida que um contêiner flexível for redimensionado, as imagens serão reduzidas conforme apropriado. Ao contrário de definir um width: 100% mais rígido, isso também garante que a imagem não seja dimensionada além do tamanho intrínseco dela. Por muito tempo, essas foram as regras de trabalhar com imagens: use um formato que os navegadores entendam, use um nível adequado de compactação e nunca dimensione imagens para cima.

Mas, por mais simples e eficaz que essa abordagem fosse visualmente, ela custava um enorme custo de desempenho. Como <img> só era compatível com uma única fonte para os dados de imagem, essa abordagem exigia um recurso de imagem com um tamanho intrínseco que fosse maior quanto o maior tamanho em que ele poderia ser exibido. Uma imagem que ocuparia um espaço em um layout que poderia ter de 300px a 2000px de largura, dependendo do tamanho da janela de visualização do usuário, exigia uma fonte de imagem com uma largura intrínseca de pelo menos 2000px. Para um usuário que só visualiza a página por meio de uma pequena janela de visualização, tudo ficaria conforme o esperado: a imagem seria dimensionada sem problemas. Na página renderizada, uma imagem de origem enorme, mas reduzida, parece não diferente de uma imagem de tamanho apropriado. No entanto, eles ainda transfeririam e renderizariam uma imagem de 2000px ampla, queimando uma enorme quantidade de largura de banda e capacidade de processamento sem nenhum benefício tangível.

As coisas pioraram com o surgimento dos primeiros dispositivos "Retina", já que a densidade da tela se tornou uma preocupação junto com o tamanho da janela de visualização. Uma origem de imagem precisa de uma largura intrínseca muito maior para se adequar a uma tela de alta densidade. Em termos simples, uma tela com o dobro de densidade exige o dobro de pixels de imagem para renderizar a imagem da maneira mais nítida possível.

Aqui, os desenvolvedores puderam confiar novamente na capacidade dos mecanismos de renderização de reduzir a escala visual das imagens. Ao fornecer ao navegador uma imagem de origem ampla 800px em src e especificar que ela deve ser exibida em 400px de largura com CSS, o resultado é uma imagem renderizada com o dobro da densidade de pixels:

Uma única imagem de origem, cortada para se adequar ao maior espaço possível no seu layout e nas telas de alta densidade, funciona visualmente para todos os usuários. Uma fonte de imagem enorme e de alta resolução renderizada em uma tela pequena e de baixa densidade se parece com qualquer outra imagem pequena e de baixa densidade, mas é muito mais lenta. O usuário precisará arcar com todos os custos de desempenho dessa enorme fonte de imagem de 4.000 pixels de largura, sem nenhum benefício.

Por muito tempo, o <img> fez apenas uma coisa: "recebeu dados de imagem e os colocou na tela". Isso foi razoavelmente bem, mas o <img> não estava à tarefa de se adaptar às mudanças radicais no contexto de navegação que estávamos enfrentando. Embora o Web design responsivo tenha se tornado uma prática de desenvolvimento comum, os navegadores otimizaram o desempenho do img por quase 20 anos. No entanto, para todos, exceto os usuários mais privilegiados, o conteúdo de imagem das páginas era ineficiente desde o início. Não importa a rapidez com que o navegador conseguiu solicitar, analisar e renderizar uma origem de imagem, esse recurso provavelmente seria muito maior do que o usuário precisava.