O formato que o Google matou em 2022 acabou de ressuscitar
Em 2022, o time do Chromium tomou uma decisão que revoltou a comunidade web: removeu o suporte experimental ao JPEG XL do Chrome. A justificativa? “Não há interesse suficiente do ecossistema.” Desenvolvedores, fotógrafos e engenheiros de compressão protestaram. Petições surgiram. O Google ignorou todas.
Quatro anos depois, o Chrome 155 acaba de embarcar o JPEG XL como padrão, habilitado por default, sem flag escondida em chrome://flags. E o plot twist: o decoder não é o mesmo código C++ de antes. É um decoder completamente novo, escrito em Rust puro, sem um único bug de memória no histórico inteiro do projeto.
Eu acompanho essa novela desde 2022 e, sinceramente, não esperava esse desfecho. Vamos entender o que mudou, por que o Rust foi decisivo, e como isso afeta cada imagem que você serve na web a partir de agora.
O que é JPEG XL (e por que você deveria ligar)
JPEG XL não é “mais um formato de imagem”. É o formato que a Joint Photographic Experts Group (sim, o mesmo grupo que criou o JPEG original em 1992) desenhou para substituir de vez o .jpg que você usa há 30 anos.
Os números são convincentes:
| Métrica | JPEG | WebP | AVIF | JPEG XL |
|---|---|---|---|---|
| ——— | —— | —— | —— | ——— |
| Compressão vs JPEG | baseline | -32% | -50% a -65% | -30% a -60% |
| Encoding speed | ~10ms | ~15ms | 200-500ms | ~20ms |
| Lossless | Não | Sim | Sim | Sim |
| HDR nativo | Não | Não | Sim | Sim |
| Progressive decode | Parcial | Não | Não | Sim (granular) |
| Transcodificação JPEG lossless | N/A | Não | Não | Sim |
Aquele último item é o que separa o JPEG XL de todos os concorrentes. Você pode pegar um .jpg existente, converter para .jxl sem perder um único bit de qualidade, e o arquivo fica cerca de 20% menor. Zero degradação. Zero re-encoding. É como comprimir um zip de um zip, só que funciona de verdade.
Para fotógrafos e sites com acervos enormes de imagens (pense em e-commerce, portais de notícias, redes sociais), isso significa migrar terabytes de conteúdo legado sem tocar na qualidade. Nenhum outro formato oferece esse caminho de migração.
Por que o Google removeu e por que voltou atrás
A remoção do JPEG XL do Chrome em 2022 gerou uma das threads mais longas da história do Chromium bug tracker: mais de 500 comentários de desenvolvedores furiosos. O argumento do Google era que o AVIF já cobria os casos de uso, que o ecossistema não tinha adotado o formato, e que manter dois codecs de próxima geração aumentava a superfície de ataque do navegador.
Esse último ponto é o que mudou tudo.
Decoders de imagem são um dos alvos favoritos de attackers. Eles processam dados binários complexos vindos direto da rede, rodam dentro do processo de renderização, e historicamente são escritos em C/C++. A lista de CVEs em decoders de imagem é assustadora: libpng, libjpeg-turbo, libwebp (lembra do CVE-2023-4863 que afetou literalmente tudo?), todos já tiveram vulnerabilidades graves de memória.
O projeto jxl-rs mudou essa equação. Um decoder JPEG XL escrito em Rust puro, com zero bugs de memória no histórico inteiro de desenvolvimento. Zero. Não “quase zero”, não “apenas dois”, zero. O time do Chrome finalmente tinha um decoder que podia embarcar sem aumentar a superfície de ataque.
jxl-rs: como o Rust convenceu o Google
O jxl-rs não é só “a mesma coisa em Rust”. É uma reimplementação completa do decoder JPEG XL que o time do Chromium adotou justamente porque resolve o problema que matou o suporte original: segurança de memória.
O código é quase inteiramente safe Rust. Onde unsafe é necessário (principalmente para otimizações SIMD), cada bloco precisa de comentários extensos de segurança e revisão obrigatória por um especialista em unsafe Rust que não seja o autor do código. Ou seja: dois pares de olhos treinados em cada linha perigosa.
A performance? Equipara (e às vezes supera) a implementação de referência em C++ (libjxl), com melhor suporte para renderização progressiva e menor consumo de memória. Isso derruba o mito de que “Rust é mais lento que C++”. Na prática, o compilador Rust e o LLVM backend geram código nativo tão eficiente quanto, com a vantagem de que metade das classes de bugs simplesmente não existem.
// Exemplo simplificado da arquitetura SIMD do jxl-rs
// A abstração jxl_simd permite código portável sem unsafe desnecessário
use jxl_simd::SimdVector;
fn inverse_dct_row(coeffs: &[f32; 8], output: &mut [f32; 8]) {
let v = SimdVector::load(coeffs);
let result = v.butterfly_8();
result.store(output);
}
A camada de abstração SIMD (jxl_simd) foi inspirada na biblioteca Highway do C++, mas adaptada para Rust com target_feature_11. Isso permite que o compilador gere instruções vetoriais (SSE, AVX2, NEON) sem que o desenvolvedor precise escrever assembly ou unsafe por toda parte.
O mapa de suporte em outubro de 2026
Aqui é onde a história fica realmente interessante. Em janeiro de 2026, o JPEG XL era suportado apenas pelo Safari (desde o Safari 17, em 2023). Cobertura global: uns míseros 16%.
Seis meses depois, o cenário mudou completamente:
| Navegador | Versão | Status | Data |
|---|---|---|---|
| ———– | ——– | ——– | —— |
| Safari | 17+ | Habilitado por padrão | Setembro 2023 |
| Chrome | 155 | Habilitado por padrão | Outubro 2026 |
| Edge | 155 | Habilitado por padrão | Outubro 2026 |
| Firefox | 157/158 | Habilitado por padrão | Outubro 2026 |
| Opera | 110+ | Habilitado por padrão | Outubro 2026 |
Quando o Firefox 157 sair (previsto para meados de outubro), a cobertura global do JPEG XL vai saltar de 16% para algo entre 85% e 90%. É a mesma faixa que o AVIF tem hoje, e o WebP levou quase uma década para atingir.
A participação do formato no Interop 2026 (o programa onde os fabricantes de navegadores se comprometem com compatibilidade cross-browser) acelerou esse alinhamento. Pela primeira vez, Chrome, Firefox e Safari concordaram em priorizar o mesmo formato de imagem.
JPEG XL vs AVIF: quando usar cada um
“Mas eu já migrei tudo pra AVIF, preciso mudar de novo?” Calma. Os dois formatos não são mutuamente excludentes, e cada um brilha em cenários diferentes.
Onde o JPEG XL ganha:
Encoding rápido. Se você gera imagens on-the-fly (thumbnails, crops, resizes em CDN), JPEG XL é 10 a 25 vezes mais rápido que AVIF para encodar. Isso é a diferença entre servir a imagem em 20ms e fazer o usuário esperar 500ms.
Migração de acervo JPEG. A transcodificação lossless é exclusiva do JPEG XL. Migrar milhões de imagens sem re-encoding? Só com .jxl.
Qualidade alta e lossless. Para fotografia profissional, imagens médicas, e arquivamento, JPEG XL consistentemente produz arquivos menores que AVIF em quality settings altos (acima de q80).
Progressive decoding granular. O JPEG XL permite renderização progressiva real: a imagem aparece embaçada e vai ganhando nitidez conforme os bytes chegam. AVIF não suporta isso.
Onde o AVIF ganha:
Compressão agressiva em qualidade baixa/média. Para imagens que não precisam ser pixel-perfect (feeds sociais, cards de preview, banners), AVIF comprime 10-15% a mais que JPEG XL.
Ecossistema maduro. CDNs como Cloudflare, Fastly e Akamai já servem AVIF automaticamente há anos. O suporte a JPEG XL em CDNs ainda está chegando.
A recomendação pragmática:
Use com fallback e sirva o melhor formato para cada browser:
<picture>
<source srcset="hero.jxl" type="image/jxl">
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Imagem hero" loading="lazy">
</picture>
Se sua CDN suporta content negotiation (via Accept header), melhor ainda: deixe o servidor decidir.
# nginx: servir JPEG XL quando o browser suporta
map $http_accept $img_suffix {
~image/jxl .jxl;
~image/avif .avif;
~image/webp .webp;
default .jpg;
}
location ~* ^(.+)\.(jpg|jpeg|png)$ {
try_files $1$img_suffix $uri =404;
}
Como converter suas imagens para JPEG XL agora
Não precisa esperar sua CDN adotar o formato. Você pode começar a gerar .jxl hoje com ferramentas open source.
Com cjxl (CLI oficial):
# Instalar libjxl (Ubuntu/Debian)
sudo apt install libjxl-tools
# Converter JPEG para JXL (lossless, sem perda)
cjxl input.jpg output.jxl
# Converter com compressão lossy (quality 80, bom equilíbrio)
cjxl input.png output.jxl -q 80
# Converter lote inteiro
find ./images -name "*.jpg" -exec sh -c \
'cjxl "$1" "${1%.jpg}.jxl"' _ {} \;
# Verificar economia de espaço
ls -lh input.jpg output.jxl
Com sharp (Node.js):
import sharp from 'sharp';
// Converter para JPEG XL
await sharp('input.jpg')
.jxl({ quality: 80, effort: 7 })
.toFile('output.jxl');
// Pipeline de build: converter todas as imagens
import { glob } from 'glob';
const images = await glob('src/images/**/*.{jpg,png}');
await Promise.all(images.map(async (img) => {
const output = img.replace(/\.(jpg|png)$/, '.jxl');
await sharp(img).jxl({ quality: 80 }).toFile(output);
}));
Com ImageMagick 7.1+:
magick input.jpg -quality 80 output.jxl
Verificando o resultado:
# Comparar tamanhos
echo "JPEG: $(stat -c%s input.jpg) bytes"
echo "JXL: $(stat -c%s output.jxl) bytes"
echo "Economia: $(echo "scale=1; (1 - $(stat -c%s output.jxl) / $(stat -c%s input.jpg)) * 100" | bc)%"
# Verificar qualidade visual (SSIM)
compare -metric SSIM input.jpg output.jxl diff.png
O impacto real: quanto bandwidth você vai economizar
Vamos fazer uma conta rápida. Suponha que seu site serve 10.000 pageviews por dia, cada página carrega 8 imagens, e o tamanho médio de cada JPEG é 150KB.
| Métrica | JPEG | JPEG XL (lossy) | JPEG XL (lossless) |
|---|---|---|---|
| ——— | —— | —————– | ——————- |
| Tamanho médio/imagem | 150 KB | 75 KB (-50%) | 120 KB (-20%) |
| Bandwidth/dia | 11.7 GB | 5.8 GB | 9.4 GB |
| Bandwidth/mês | 351 GB | 175 GB | 281 GB |
| Economia mensal (CDN ~$0.08/GB) | baseline | $14.08 | $5.60 |
Para um site pequeno, $14 por mês não parece muito. Mas escale para 1 milhão de pageviews/dia (um portal de médio porte) e você está economizando $1.408/mês, ou quase $17.000 por ano. Só trocando o formato da imagem.
E isso sem contar o impacto no Core Web Vitals. Imagens menores significam LCP (Largest Contentful Paint) mais rápido, que impacta diretamente seu ranking no Google. Cada 100ms conta.
O elefante na sala: e o WebP?
WebP não vai desaparecer amanhã. Ele tem 96% de cobertura global, todos os CDNs e CMSs do planeta já suportam, e ferramentas como WordPress e Next.js convertem automaticamente para WebP há anos.
Mas o WebP tem limitações técnicas reais. Ele é baseado no codec VP8 (vídeo do YouTube de 2010), não suporta HDR, não tem progressive decoding decente, e a qualidade em compressão agressiva fica visivelmente pior que AVIF ou JPEG XL. Para 2026, ele é o “bom o suficiente” que eventualmente vai perder espaço, assim como o GIF perdeu para APNG e WebP animado.
A transição não vai acontecer de uma vez. O mais provável é que nos próximos 2 a 3 anos, o pipeline de imagens padrão evolua de “JPEG com fallback WebP” para “JPEG XL com fallback AVIF com fallback WebP com fallback JPEG”. Quatro camadas, sim. Mas CDNs como Cloudflare já fazem isso automaticamente no edge, então na prática você configura uma vez e esquece.
Rust no Chrome: maior que JPEG XL
O jxl-rs não é o primeiro código Rust a entrar no Chrome, mas é um dos mais significativos. Ele valida a estratégia do Google de migrar componentes críticos de segurança para linguagens memory-safe.
Já temos Rust no Chrome para: o verificador de certificados, partes do networking stack, e agora o decoder JPEG XL. Cada componente novo em Rust é um pedaço do Chrome que simplesmente não pode ter buffer overflow, use-after-free, ou double-free. O custo de encontrar e corrigir esses bugs (estimado em $150.000 por vulnerabilidade crítica, entre bounty, engenharia e release de emergência) cai para zero nessas áreas.
Para a comunidade Rust, é uma validação enorme. Para desenvolvedores web, significa que os browsers estão ficando mais seguros sem ficarem mais lentos. E para quem ainda pergunta “Rust é production-ready?”, bom, seu navegador já roda Rust enquanto você lê isso.
Como detectar suporte no seu código
Se você quer progressive enhancement sem depender de , pode detectar suporte via JavaScript:
async function supportsJxl() {
const jxlTestImage =
'/yD/SABIAQoAEAAASAABGP/yABZO' +
'x0QASABIAAH/8AAI//gAA';
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(img.width === 1);
img.onerror = () => resolve(false);
img.src = `data:image/jxl;base64,${jxlTestImage}`;
});
}
// Uso
if (await supportsJxl()) {
document.documentElement.classList.add('jxl');
}
/* CSS: trocar background apenas quando JXL é suportado */
.hero {
background-image: url('/images/hero.jpg');
}
.jxl .hero {
background-image: url('/images/hero.jxl');
}
Mas honestamente? O é mais limpo e funciona sem JavaScript. Use a detecção JS apenas para backgrounds CSS ou situações onde o HTML não tem disponível.
O que fazer agora (checklist prático)
Se você mantém um site, app ou plataforma que serve imagens, aqui vai o que fazer nos próximos 30 dias:
- Instale as ferramentas:
libjxl-toolsno servidor,sharpno pipeline Node.js - Gere versões .jxl: comece pelos assets estáticos (hero images, logos, ícones)
- Configure
: adicionecomo primeira opção - Teste no Chrome 155: abra
chrome://versione confirme que está na 155+ - Monitore Core Web Vitals: compare LCP antes e depois da migração
- Configure content negotiation: se usa nginx/Caddy, adicione a regra de Accept header
- Para acervos legados: use transcodificação lossless (
cjxl foto.jpg foto.jxl) e economize 20% sem perder qualidade
A web levou 30 anos para substituir o JPEG. Parece que agora, finalmente, tem um sucessor que todos os browsers concordam em suportar. O JPEG XL não é perfeito, nenhum formato é. Mas é o mais completo que já existiu, e com Chrome, Firefox, Safari e Edge a bordo, não tem mais desculpa para não começar a usar.













