El elemento picture con fallback JPG
El elemento HTML <picture> es la forma más fiable de servir WebP con fallback para navegadores antiguos. Permite que el navegador elija el mejor formato disponible sin ningún JavaScript:
<picture>
<source srcset="hero.webp" type="image/webp">
<source srcset="hero.jpg" type="image/jpeg">
<img src="hero.jpg" alt="Hero banner" width="1200" height="630"
loading="lazy" decoding="async">
</picture>
Cuando el navegador soporta WebP, descarga hero.webp. En caso contrario, recurre a hero.jpg. La etiqueta <img> actúa como fallback final y contiene los atributos alt, width, height y de carga.
Para imágenes responsivas, combina el elemento <picture> con srcset y sizes para servir distintas resoluciones según el ancho del viewport:
<picture>
<source
srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1200.webp 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 600px"
type="image/webp">
<img
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 600px"
src="photo-800.jpg" alt="Product photo" width="800" height="600"
loading="lazy" decoding="async">
</picture>
¿Todavía necesitas fallback JPG? En 2026, más del 99 % de los navegadores soportan WebP. Si tus analíticas no muestran tráfico de Internet Explorer, puedes servir WebP directamente en una etiqueta <img> estándar. El elemento <picture> sigue siendo útil si quieres servir AVIF como primera opción con WebP como fallback.
Negociación de contenido en el servidor
La negociación de contenido comprueba la cabecera Accept del navegador y sirve WebP de forma transparente — sin cambios en el HTML. Cuando un navegador solicita una imagen e incluye image/webp en su cabecera Accept, el servidor responde con la versión WebP.
Configuración de Nginx
Añade esto a tu bloque server de Nginx para servir variantes WebP cuando existan junto a los archivos originales:
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
server {
location ~* \.(jpe?g|png)$ {
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
}
}
Esto comprueba si existe un archivo .webp junto al original (p. ej., photo.jpg.webp al lado de photo.jpg). Si el navegador soporta WebP y el archivo existe, Nginx lo sirve. La cabecera Vary: Accept garantiza que los CDN y cachés proxy almacenen versiones separadas para distintas capacidades del navegador.
Reglas .htaccess de Apache
Para servidores Apache, añade estas reglas de reescritura a tu archivo .htaccess:
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_FILENAME}.webp -f
RewriteRule ^(.+)\.(jpe?g|png)$ $1.$2.webp [T=image/webp,L]
Header append Vary Accept env=REDIRECT_accept
El mismo principio aplica: si el navegador acepta WebP y existe una variante .webp en disco, Apache la sirve de forma transparente. No se requieren cambios en el HTML.
Soluciones de conversión automática por CDN
El enfoque más sencillo para la mayoría de sitios web es dejar que tu CDN gestione la conversión a WebP automáticamente. Subes los originales en JPG/PNG y el CDN sirve WebP optimizado a los navegadores compatibles con cero cambios de código.
| CDN / Servicio | Función | Configuración |
|---|---|---|
| Cloudflare Polish | WebP automático + compresión | Toggle de un clic (plan Pro+) |
| Cloudinary | Formato automático via f_auto | Añade f_auto a la URL de la imagen |
| imgix | Formato automático via auto=format | Parámetro en la URL |
| AWS CloudFront | Conversión con Lambda@Edge | Función Lambda personalizada |
| Vercel / Netlify | Optimización de imágenes integrada | Automático con el componente Image |
Las soluciones basadas en CDN gestionan automáticamente la negociación de contenido, el caché y su invalidación. Son el enfoque recomendado para sitios dinámicos donde usuarios o editores de contenido suben imágenes — como no puedes predecir qué imágenes aparecerán, la conversión automática es esencial.
Configuración de WebP en WordPress
WordPress 5.8+ soporta subidas WebP de forma nativa, pero necesitas un plugin para convertir las imágenes existentes y servirlas de forma óptima:
- ShortPixel Image Optimizer: Convierte imágenes existentes a WebP al vuelo. Sirve WebP mediante el elemento
<picture>o reescritura .htaccess. Nivel gratuito: 100 imágenes/mes - Imagify: Conversión masiva con tres niveles de calidad (normal, agresivo, ultra). Se integra con WP Rocket para caché. Nivel gratuito: 20 MB/mes
- EWWW Image Optimizer: Genera copias WebP automáticamente al subir. Reescribe las URL de las imágenes vía plugin o CDN. Optimización local gratuita e ilimitada
- WebP Express: Plugin ligero centrado exclusivamente en la conversión a WebP. Configura .htaccess o usa servicio basado en PHP. Gratuito y de código abierto
Para la mayoría de sitios WordPress, ShortPixel o EWWW son las opciones más seguras. Cubren el pipeline completo: convertir al subir, generar variantes WebP, reescribir el HTML para servir WebP y hacer fallback a JPG/PNG en navegadores incompatibles.
Integración con herramientas de build
Para sitios estáticos y frameworks JavaScript (React, Vue, Next.js, Nuxt), integra la generación de WebP en tu pipeline de build para que las imágenes se conviertan automáticamente en tiempo de compilación.
Webpack (image-minimizer-webpack-plugin)
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
new ImageMinimizerPlugin({
generator: [{
preset: "webp",
implementation: ImageMinimizerPlugin.sharpGenerate,
options: { encodeOptions: { webp: { quality: 80 } } }
}]
})
]
}
};
Vite (vite-plugin-imagemin)
import viteImagemin from "vite-plugin-imagemin";
export default defineConfig({
plugins: [
viteImagemin({
webp: { quality: 80 }
})
]
});
La conversión en tiempo de build funciona bien para sitios con un conjunto conocido de imágenes (páginas de marketing, documentación, blogs). Para contenido subido por usuarios, prefiere soluciones basadas en CDN que procesen las imágenes dinámicamente.
Ajustes de calidad óptimos
Elegir el ajuste de calidad WebP correcto es clave. Demasiado bajo y aparecen artefactos visibles; demasiado alto y pierdes los beneficios de tamaño. Aquí tienes los valores recomendados por tipo de contenido:
| Tipo de contenido | Calidad recomendada | Notas |
|---|---|---|
| Fotos (productos, retratos) | 75–85 | Mejor equilibrio entre calidad y tamaño |
| Banners hero / marketing | 80–90 | Mayor calidad para imágenes grandes y prominentes |
| Miniaturas / previsualizaciones | 70–80 | El tamaño pequeño oculta los artefactos |
| Gráficos / ilustraciones | 80–90 | Las áreas de color plano son más sensibles a artefactos |
| Capturas / texto prominente | Sin pérdida | La calidad del texto se degrada notablemente con compresión con pérdida |
Punto de partida: La calidad 80 es el punto óptimo para la mayoría del contenido fotográfico. Produce resultados visualmente indistinguibles de JPG calidad 85 con un tamaño de archivo aproximadamente un 30 % menor. Prueba con tus imágenes específicas y ajusta desde ahí.
Medir el impacto
Tras implementar WebP, mide la mejora de rendimiento real con estas herramientas:
- Google Lighthouse: Ejecuta auditorías antes y después del cambio. Comprueba el diagnóstico "Serve images in next-gen formats" — debería desaparecer. Compara la puntuación de Performance, LCP y Total Blocking Time
- PageSpeed Insights: Prueba versiones móvil y escritorio desde los servidores de Google. La sección "Opportunities" ya no debería listar la optimización de imágenes como recomendación
- WebPageTest: Proporciona gráficos de cascada detallados con los tiempos de carga de cada imagen. Compara las vistas de filmstrip antes y después para ver las diferencias en velocidad de renderizado visual
- Pestaña Network de Chrome DevTools: Filtra por tipo "Img" y compara el tamaño total transferido. Verifica que la cabecera
Content-Typemuestreimage/webpen las imágenes convertidas - Core Web Vitals de Search Console: Monitoriza los datos de campo durante 2–4 semanas tras el cambio. Busca mejoras en LCP y en el porcentaje general de "URLs buenas"
Consideraciones sobre lazy loading
WebP y lazy loading se complementan para maximizar el rendimiento, pero hay detalles de implementación importantes:
- Imágenes above-the-fold: NO uses lazy loading en tu imagen hero ni en ninguna imagen visible en la carga inicial. Usa
loading="eager"(el valor por defecto) y añadefetchpriority="high"para la imagen LCP - Imágenes below-the-fold: Usa
loading="lazy"en el resto de imágenes. El navegador aplaza la carga hasta que el usuario se desplaza cerca de ellas - Define siempre las dimensiones: Incluye atributos explícitos
widthyheighten cada etiqueta<img>para evitar el Cumulative Layout Shift (CLS) - Decodificación asíncrona: Añade
decoding="async"para que el navegador decodifique las imágenes fuera del hilo principal
<!-- Hero image: eager loading, high priority -->
<img src="hero.webp" alt="..." width="1200" height="630"
fetchpriority="high" decoding="async">
<!-- Below-the-fold: lazy loading -->
<img src="product.webp" alt="..." width="600" height="400"
loading="lazy" decoding="async">