Bun.Image torna todo o seu pipeline de imagens obsoleto

BBetter Stack
Computing/SoftwareInternet Technology

Transcript

00:00:00Este é o Bun Image, uma API de processamento de imagens integrada lançada no Bun 1.3.14 que pode redimensionar,
00:00:06cortar e converter imagens entre diferentes formatos sem dependências nativas,
00:00:10e tudo roda fora da thread principal, o que significa que não vai bloquear o seu servidor enquanto estiver
00:00:14processando. Mas o Bun já é um runtime, um gerenciador de pacotes, um bundler, um executor de testes,
00:00:19e agora também é um processador de imagens? Será que isso é exagero ou está nos dizendo algo
00:00:24maior sobre o rumo do Bun? Clique em se inscrever e vamos descobrir.
00:00:30Se você já processou imagens no servidor com JavaScript, talvez tenha usado uma biblioteca chamada
00:00:35Sharp sem nem saber, que tem mais de 55 milhões de downloads por semana no npm, e que é até
00:00:41usada pelo Next.js por baixo dos panos para otimização de imagens. Mas o Sharp depende de um binário nativo chamado libvips,
00:00:47o que significa que cada instalação precisa baixar a versão certa para a sua plataforma. E se você já teve
00:00:51uma build no Docker ou pipeline de CI falhando por causa disso, sabe exatamente quão frustrante isso é. Então o Bun decidiu
00:00:57simplesmente embutir o processamento de imagens no próprio runtime, e ele é na verdade mais rápido que o Sharp em
00:01:02quase todos os benchmarks. A leitura de metadados é cerca de 70 vezes mais rápida, e o redimensionamento é uns 30% mais rápido. Agora, muitos
00:01:08desenvolvedores estão confusos sobre o porquê de o Bun ter adicionado isso, mas eu consigo ver para onde tudo isso está indo,
00:01:13e vou falar mais sobre isso daqui a pouco. Mas por ora, vamos ver algumas demonstrações de como usar
00:01:17a API de imagem do Bun. E vamos testá-la no meu blog, que é um site estático em Waku, que tem
00:01:22algumas imagens bem grandes. Para começar, vamos ver um script simples que otimiza uma imagem,
00:01:27que é a foto de perfil com o meu rosto, sendo capaz de reduzir o tamanho em 99%, o que é insano.
00:01:33Vamos ver como. Primeiro, pegamos a imagem, e note que estamos usando Bun.image aqui, mas você também pode usar
00:01:37o Bun file com a função de imagem. Depois, redimensionamos a imagem para reduzir seu tamanho, definindo a largura para 800
00:01:43pixels, e a altura é calculada automaticamente com base na proporção. Mas se você quiser,
00:01:47podemos adicionar isso aqui também. Em seguida, definimos o formato de saída como WebP com qualidade reduzida. É
00:01:52claro que outros formatos de saída são suportados, e então salvamos a nova imagem em um arquivo,
00:01:56o que retorna uma promise, exigindo o uso do await. E você pode ver como isso é simples.
00:02:01Na verdade, todo este código aqui é desnecessário, então podemos removê-lo e deixar o código ainda mais simples.
00:02:06Também podemos definir um filtro de redimensionamento, mudando o kernel de amostragem para reduzir ainda mais o tamanho da imagem.
00:02:10Podemos girar ou inverter a imagem, o que é bem legal. Podemos até alterar o brilho ou
00:02:15a saturação, o que pode gerar resultados um tanto estranhos. Mas há algo muito inteligente que
00:02:19você pode fazer para conexões lentas, que é usar a função de placeholder para exibir automaticamente
00:02:23uma imagem borrada enquanto a principal é carregada. E para fazer isso, tenho este loop que
00:02:29percorre cada arquivo que contém essas extensões dentro do diretório que armazena todas
00:02:34as imagens do blog. Assim, cada imagem é redimensionada, reduzida sem ser cortada,
00:02:39e sem ter a resolução aumentada. Depois, criamos um placeholder para cada imagem, gerando um thumb hash, o que significa codificar
00:02:45qualquer imagem em um hash de 28 bytes, perfeito como placeholder de imagem borrada.
00:02:49Esse hash é adicionado a um objeto de placeholders, e então gravado em um arquivo,
00:02:53que fica com essa aparência. Agora, o motivo de o placeholder ser uma imagem base64 em vez de um
00:02:58arquivo WebP menor separado é para que a rede não precise fazer uma requisição para buscá-lo.
00:03:02Portanto, o que posso fazer é importar todos os placeholders e adicioná-los como imagem de fundo no CSS,
00:03:07enquanto espero a imagem principal carregar, o que funcionará para todas as imagens do meu blog.
00:03:11Mas se você quiser fazer isso para uma única imagem em um arquivo MDX, basta adicionar o código base64
00:03:16manualmente, o que funciona super bem. Note que você também pode obter um comportamento semelhante usando
00:03:20imagens JPEG definindo progressive como true. Claro, existem muitas outras coisas que o Bun Image
00:03:24suporta e que ainda não mencionei, como obter imagens de um bucket compatível com S3,
00:03:28ou salvar imagens em um bucket, usar o pipeline de imagem como um corpo de resposta válido,
00:03:33e configurar um formato alternativo caso um sistema operacional específico não suporte um determinado tipo.
00:03:37Então, vale a pena usar? Bem, se você já usa o Bun, então sim, é uma escolha óbvia.
00:03:41Mas se você usa Node, o Sharp funciona muito bem e já foi bastante testado em produção,
00:03:45e não há necessidade de mudar para um runtime completamente diferente só por causa de processamento de imagens.
00:03:49Lembra quando eu disse que há um motivo maior para o Bun ter adicionado isso? Bem, se você olhar o que o Bun vem
00:03:54fazendo no último ano: SQLite integrado, S3, Postgres e agora imagens, isso é basicamente
00:03:59tudo o que você precisa para uma aplicação full-stack, exceto talvez autenticação e envio de e-mails. Mas isso me faz pensar,
00:04:04será que o Bun está tentando criar o Laravel ou o Rails do JavaScript, mas a nível de runtime? Se estiver,
00:04:11então a próxima coisa em que vão trabalhar é autenticação. E se for isso, lembre-se, você ouviu aqui primeiro.
00:04:15Mas infelizmente, hoje em dia, não dá para falar de Bun sem mencionar a enorme reescrita de Zig para Rust,
00:04:20que, com sorte, será lançada na próxima versão. Vamos torcer para que tudo ocorra bem.
00:04:25Por falar em Zig, se você quiser saber mais sobre a Language Zero da Vercel, que se parece com Zig,
00:04:29mas não é Zig, e foi feita para agentes de IA, confira este vídeo do James.

Key Takeaway

O Bun 1.3.14 integrou o Bun.Image nativamente para substituir dependências como o Sharp, superando-o em velocidade de processamento e apontando para um runtime com ferramentas full-stack completas.

Highlights

  • O Bun 1.3.14 introduziu o Bun.Image, uma API de processamento de imagens integrada que opera fora da thread principal sem dependências nativas.

  • A leitura de metadados pelo Bun.Image executa cerca de 70 vezes mais rápido e o redimensionamento atinge velocidade 30% superior em comparação à biblioteca Sharp.

  • O código otimiza fotos de perfil reduzindo o tamanho em até 99% através da conversão para o formato WebP com largura definida em 800 pixels.

  • A função de hash de 28 bytes gera placeholders borrados em base64 para carregamento em conexões lentas sem requisições de rede adicionais.

  • O ecossistema do Bun integra SQLite, S3, Postgres e processamento de imagens, concentrando os recursos essenciais para aplicações full-stack.

Timeline

Apresentação da API Bun.Image

  • O Bun 1.3.14 adiciona o Bun.Image para redimensionar, cortar e converter imagens sem dependências nativas.
  • O processamento ocorre fora da thread principal para evitar o bloqueio do servidor.
  • A biblioteca Sharp acumula mais de 55 milhões de downloads semanais no npm, mas depende do binário nativo libvips.
  • O Bun.Image supera o Sharp com leituras de metadados 70 vezes mais rápidas e redimensionamento 30% mais rápido.

O processamento de imagens em JavaScript frequentemente utiliza o Sharp, cuja dependência do libvips causa falhas frequentes em builds do Docker e pipelines de CI. Para solucionar esse atrito, o Bun integrou a funcionalidade diretamente no runtime. Testes práticos demonstram reduções drásticas no tamanho de arquivos de imagem com scripts simples baseados em WebP e largura customizada.

Otimização e Geração de Placeholders

  • A função de placeholder gera um thumb hash de 28 bytes para exibir uma imagem borrada durante o carregamento.
  • O armazenamento em base64 elimina a necessidade de requisições de rede adicionais para buscar arquivos menores.
  • O pipeline suporta integração com buckets compatíveis com S3 e respostas HTTP diretas.

Conexões lentas beneficiam-se de placeholders borrados gerados em lote a partir do diretório de imagens do blog. A codificação em base64 permite inserir o fundo diretamente no CSS enquanto a imagem principal é transferida pela rede. Além disso, a API gerencia formatos alternativos para sistemas operacionais específicos e opera diretamente com armazenamento em nuvem.

Visão Geral do Ecossistema e Perspectivas

  • O uso do Bun.Image compensa para quem já adota o runtime do Bun, enquanto projetos em Node continuam respaldados pelo Sharp.
  • A inclusão contínua de SQLite, S3, Postgres e imagens aproxima o Bun de um framework full-stack a nível de runtime.
  • A reescrita de Zig para Rust planeja novas versões iminentes para o projeto.

A estratégia recente do Bun consolida ferramentas tradicionalmente externas diretamente no núcleo do runtime. A presença de banco de dados, armazenamento, imagens e banco relacional estrutura uma base comparável a frameworks consolidados como Laravel ou Rails. O ecossistema aguarda atualizações focadas na transição de linguagem e novos recursos de infraestrutura.

Community Posts

View all posts