wandres.dev
IMÁGENES I · Formatos y compresión

Elegir el formato según el tipo de imagen

Fotografía, ilustración plana, captura con texto, transparencia e iconos: los cinco casos tienen ganadores distintos, y en dos de ellos el formato moderno pierde por goleada.

⏱ 21 min

“AVIF es un cincuenta por ciento más pequeño que JPEG” es una frase cierta sobre fotografía y falsa sobre casi todo lo demás. Los codificadores modernos están afinados para contenido natural, y en cuanto la imagen tiene bordes duros, colores planos o texto pequeño, la jerarquía se reordena entera y a veces se invierte. Elegir formato sin distinguir el tipo de imagen es cómo se acaba sirviendo una captura de pantalla de 234 KB creyendo que se está optimizando.

🎯 Al terminar esta lección sabrás
  • Dar cifras por tipo de imagen en lugar de una cifra global.
  • Reconocer los dos casos en los que un formato moderno con pérdida es peor que PNG.
  • Cuantificar la sobrecarga de contenedor que hace a AVIF inviable en iconos.
  • Montar una canalización que decida el formato midiendo en lugar de suponiendo.

Los cinco tipos y su ganador

Fotografía

Es el caso para el que se diseñaron los códecs modernos y donde su ventaja es la publicada.

  • WebP con pérdida es entre un 25 y un 34 % más pequeño que JPEG a igualdad de índice de similitud estructural. Es la cifra que publica el propio proyecto sobre su corpus de prueba.
  • AVIF ronda el 50 % de reducción frente a JPEG a calidad equivalente, y entre un 10 y un 30 % frente a WebP según el contenido.

La ventaja de AVIF crece con la resolución y con la cantidad de detalle fino, y se estrecha en fotografías pequeñas o muy lisas. Aquí el submuestreo de crominancia es inocuo, la profundidad de 8 bits sobra salvo en material de alto rango dinámico, y el orden de preferencia no admite discusión: AVIF, WebP, JPEG progresivo.

Un matiz que sí importa: la reserva JPEG conviene generarla progresiva, porque en una conexión mala muestra una versión reconocible con una fracción de los bytes en lugar de dibujarse por franjas.

Ilustración plana, logotipos y diagramas

Aquí cambia todo, y el motivo es estructural: los códecs con pérdida se basan en transformadas que representan bien los degradados suaves y mal los bordes duros, que es de lo único que está hecha una ilustración plana.

Cifras medidas sobre una ilustración sintética de 1.200 por 800 con bloques de color sólido y bordes limpios. Los valores absolutos dependen de la imagen; lo que se mantiene es el orden y la magnitud de las diferencias:

Codificación Tamaño
WebP sin pérdida 1.702 B
PNG de 8 bits con paleta de 64 colores 3.445 B
AVIF, modo sin pérdida 5.017 B
AVIF con pérdida, calidad 85 5.484 B
PNG de 24 bits 7.001 B
WebP con pérdida, calidad 85 11.124 B
JPEG calidad 85 35.647 B

Dos lecturas que contradicen la intuición.

JPEG es cinco veces más grande que un PNG sin pérdida en este contenido. No es una anomalía: es lo que ocurre siempre que aplicas un códec de fotografía a contenido gráfico. Y encima el resultado tiene zumbido visible alrededor de cada borde.

El ganador es un formato sin pérdida, y por un factor de cuatro sobre el PNG equivalente. WebP sin pérdida no es el mismo códec que WebP con pérdida: es un formato distinto, con predicción espacial, y es excepcionalmente bueno en contenido gráfico.

Antes de todo esto, la pregunta correcta: si la ilustración es vectorial, sírvela en SVG. Un logotipo en SVG pesa cientos de bytes, escala a cualquier densidad sin variantes, se puede recolorear con CSS y no necesita ni picture ni negociación. Cualquier comparación de formatos raster para un logotipo es una discusión que no debería estar ocurriendo.

Capturas de pantalla con texto

El caso más extremo, y el que produce el desastre del título.

Mismas dimensiones, contenido de interfaz con texto de 15 píxeles:

Codificación Tamaño
WebP sin pérdida 8.360 B
AVIF, modo sin pérdida 15.422 B
AVIF con pérdida, calidad 85 17.761 B
PNG de 8 bits con paleta 34.702 B
WebP con pérdida, calidad 85 76.022 B
PNG de 24 bits 114.374 B
JPEG calidad 85 124.999 B
AVIF con pérdida, calidad 100 y crominancia completa 233.947 B

La última fila es el resultado de hacer lo que parece más prudente: subir la calidad al máximo porque hay texto y no queremos perderlo. El archivo resultante es veintiocho veces el del ganador y el doble que un PNG sin comprimir bien. La curva de tasa contra distorsión de un códec de transformada se vuelve patológica en la cima cuando el contenido son bordes perfectamente afilados: gastar bits en reproducirlos exactamente con una transformada es carísimo comparado con describirlos.

Las conclusiones operativas:

Usa un formato sin pérdida. WebP sin pérdida es exacto bit a bit y aquí es trece veces más pequeño que el PNG de 24 bits.

Deja PNG con paleta como reserva. Una captura de interfaz suele tener menos de 256 colores distintos, y la conversión a paleta reduce el PNG a un tercio sin que se note.

Si tienes que usar pérdida, mide. AVIF a calidad 85 se comporta razonablemente aquí, y hay que comprobar el zumbido alrededor de las letras a escala real, no reducido.

Y antes que nada: comprueba si tiene que ser una imagen. Un bloque de código en una captura es texto que no se puede copiar, no se puede buscar, no se puede leer con un lector de pantalla y no se adapta al tamaño de letra del usuario. Casi siempre debería ser texto marcado.

Transparencia

El caso donde el ahorro es mayor y donde menos se aplica, porque la costumbre lleva directa a PNG.

El motivo es una limitación del formato: PNG no tiene modo con pérdida. Una fotografía recortada con canal alfa, servida en PNG, se codifica sin pérdida entera, y eso significa cientos de kilobytes para algo que en JPEG serían cuarenta, si JPEG admitiera transparencia, que no la admite.

WebP y AVIF sí combinan pérdida y canal alfa. Para una foto de producto recortada sobre fondo transparente, el salto típico va de varios cientos de kilobytes a unas pocas decenas. Es, con diferencia, la sustitución de formato con mejor relación entre esfuerzo y bytes ahorrados que existe en un catálogo de comercio electrónico.

La reserva es incómoda porque no hay ninguna universal con pérdida y transparencia. Dos salidas: dejar PNG como último recurso asumiendo su peso para el pequeño porcentaje que lo necesite, o componer el fondo en el servidor y servir JPEG con el color de fondo ya aplicado cuando el diseño lo permita.

Iconos y sellos diminutos

Aquí AVIF pierde siempre, y por una razón que no tiene nada que ver con la compresión: el contenedor. Un archivo AVIF lleva una estructura de cajas de metadatos con un mínimo fijo de unos cientos de bytes, que en una imagen de veinte bytes de datos es todo el archivo.

Medido sobre un icono liso con una forma simple:

Tamaño PNG WebP sin pérdida AVIF
1 x 1 69 B 38 B 306 B
16 x 16 131 B 68 B 366 B
32 x 32 186 B 90 B 466 B
64 x 64 291 B 128 B 563 B

AVIF es entre cuatro y ocho veces más grande que la mejor opción en todo ese rango, y el cruce no llega hasta bastante más arriba. La regla práctica: por debajo de unos 100 píxeles de lado, no uses AVIF. Y la regla mejor: los iconos son gráficos vectoriales, van en SVG, y si son muchos van en un solo archivo con símbolos referenciados, con lo que el problema del número de peticiones desaparece también.

El árbol de decisión

  1. ¿Es vectorial o se puede dibujar como vectorial? SVG. Fin.
  2. ¿Es texto? Márcalo como texto. Fin.
  3. ¿Mide menos de 100 píxeles de lado? WebP sin pérdida o PNG. AVIF no.
  4. ¿Es contenido gráfico plano, con bordes duros o texto? Formato sin pérdida, empezando por WebP sin pérdida, con PNG con paleta de reserva.
  5. ¿Necesita transparencia con contenido fotográfico? AVIF y WebP con pérdida y canal alfa, PNG de reserva.
  6. ¿Es fotografía? AVIF, WebP, JPEG progresivo, en ese orden.
  7. ¿Es alto rango dinámico o más de 8 bits por canal? AVIF, que es el único de los cuatro que lo admite.

Que lo decida la balanza

Mantener este árbol en la cabeza de un equipo no escala. Lo que sí escala es una canalización que genere todos los candidatos y se quede con el más pequeño que alcance el objetivo de calidad, con lo que la clasificación por tipo deja de ser una decisión humana y pasa a ser un resultado.

#!/usr/bin/env bash
# Genera candidatos y conserva el mas pequeno que alcanza el objetivo.
# Uso: ./mejor.sh original.png 80
set -euo pipefail

origen="$1"
objetivo="${2:-80}"
base="${origen%.*}"
tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT

# Candidatos: dos sin perdida y tres con perdida a distintas calidades.
cwebp  -z 9 -lossless "$origen" -o "$tmp/webp-ll.webp"  >/dev/null 2>&1
avifenc --lossless "$origen" "$tmp/avif-ll.avif"        >/dev/null 2>&1
for q in 60 75 85; do
  cwebp  -q "$q" -m 6 "$origen" -o "$tmp/webp-$q.webp"  >/dev/null 2>&1
  avifenc -q "$q" -s 4 "$origen" "$tmp/avif-$q.avif"    >/dev/null 2>&1
done

mejor=""; mejorBytes=999999999
for c in "$tmp"/*; do
  case "$c" in
    *.webp) dwebp   "$c" -o "$tmp/d.png" >/dev/null 2>&1 ;;
    *.avif) avifdec "$c"    "$tmp/d.png" >/dev/null 2>&1 ;;
  esac
  nota=$(ssimulacra2 "$origen" "$tmp/d.png")
  bytes=$(wc -c < "$c")
  printf '%-16s %8s B  nota %s\n' "$(basename "$c")" "$bytes" "$nota"
  if [ "$(echo "$nota >= $objetivo" | bc -l)" -eq 1 ] && [ "$bytes" -lt "$mejorBytes" ]; then
    mejor="$c"; mejorBytes=$bytes
  fi
done

[ -n "$mejor" ] || { echo "Ningun candidato alcanza $objetivo"; exit 1; }
cp "$mejor" "$base.${mejor##*.}"
echo "Ganador: $(basename "$mejor") con $mejorBytes bytes"

Los candidatos sin pérdida participan en la comparación en igualdad de condiciones: obtienen una puntuación de 100, así que siempre superan el umbral, y ganan cuando además pesan menos. Es exactamente lo que pasa con la ilustración plana y con la captura de pantalla, sin que nadie haya tenido que clasificarlas.

⚠️
El formato ganador puede variar entre dos imágenes de la misma sección, y eso es correcto

Si la canalización decide por imagen, tu catálogo tendrá WebP sin pérdida en unas fichas y AVIF con pérdida en otras. Es la respuesta correcta y desconcierta a quien espera uniformidad. Lo que sí conviene es registrar la decisión y el motivo junto al archivo generado, para que cuando alguien pregunte por qué esta imagen es WebP haya una respuesta con un número detrás en lugar de un encogimiento de hombros.

Quedarse con el archivo más pequeño es la regla correcta hasta que el dispositivo del usuario es el cuello de botella, y entonces es la equivocada

La canalización de arriba optimiza una sola variable, los bytes transferidos, y esa es la variable correcta mientras la red sea el recurso escaso. Deja de serlo en un caso concreto y bastante común: una página con muchas imágenes simultáneas en un móvil de gama baja. Ahí el coste dominante no es descargar sino decodificar, y la decodificación de AVIF es notablemente más cara que la de JPEG o la de WebP porque está reconstruyendo un fotograma de un códec de vídeo moderno. En una galería con cuarenta miniaturas, elegir AVIF puede ahorrarte cien kilobytes de red y costarte varios cientos de milisegundos de hilo principal en el dispositivo del percentil bajo de tu audiencia, con impacto directo en la interacción y ninguno visible en tu panel de bytes. La consecuencia práctica es que la regla del más pequeño necesita un desempate: cuando la diferencia de tamaño entre dos candidatos es menor que un umbral, elige el más barato de decodificar, que en la práctica significa preferir WebP sobre AVIF en las variantes pequeñas y numerosas y reservar AVIF para las grandes y pocas, que es justo donde su ventaja de compresión es mayor en términos absolutos. La forma de detectar que te está pasando no es mirar el peso: es mirar el tiempo de decodificación en el perfil de rendimiento, y muy especialmente el retraso de renderizado del que hablamos en las cuatro subpartes, porque las imágenes se decodifican y se pintan en el mismo hilo que atiende los toques del usuario.