Optimizar la Carga de Imágenes en tu Sitio Web con Placeholders
Aprende a implementar de manera vanilla y saber cómo funciona la técnica Low Quality Image Placeholders (LQIP) para mejorar la forma en que cargan las imágenes en tu sitio web y ofrecer una experiencia de usuario más fluida.
¿Qué son los placeholders y la técnica LQIP?
Los placeholders (o marcadores de posición) son recursos visuales —como colores, degradados o versiones reducidas de imágenes— que se muestran temporalmente mientras las imágenes reales y de mayor calidad se cargan. Su objetivo es evitar espacios vacíos o brindar feedback a los usuarios, mejorando la percepción de velocidad durante la carga del sitio web.
Una de las implementaciones más efectivas de esta técnica es LQIP (Low Quality Image Placeholder), que consiste en generar una versión pequeña y borrosa de una imagen para mostrarla como previsualización, mientras el archivo en alta resolución se descarga en segundo plano.
De esta forma, el usuario percibe una carga más fluida, ya que el contenido visual nunca aparece de golpe.
Esta técnica puede combinarse con la propiedad loading y su valor lazy, que permite cargar imágenes de forma diferida de manera nativa en los navegadores modernos, optimizando aún más el rendimiento del sitio.
¿Por qué las imágenes afectan el rendimiento?
Las imágenes pueden ser uno de los recursos más pesados de cualquier sitio web, y si no están optimizadas correctamente, pueden ralentizar considerablemente la carga y el renderizado de la página.
Las imágenes siempre se muestran solo cuando se han descargado completamente, lo que puede generar una sensación de lentitud si el resto del contenido ya es visible.
Un ejemplo típico ocurre cuando el usuario ve espacios vacíos o saltos de diseño mientras espera a que las imágenes terminen de cargarse:
- Sin placeholders: la imagen aparece de golpe cuando termina de descargarse.
- Con placeholders: el espacio está ocupado por una versión borrosa o de baja calidad que se reemplaza suavemente por la imagen final cuando está lista.
De esta manera, LQIP permite mejorar la percepción visual de velocidad, incluso si el tiempo real de carga no cambia drásticamente.
¿Cómo implementar LQIP?
Para aplicar la técnica LQIP (Low Quality Image Placeholder) necesitaremos generar versiones en miniatura de nuestras imágenes y utilizarlas como previsualización mientras las imágenes originales se cargan en segundo plano.
En este ejemplo debes tener instalado Node.js (recomiendo instalar la última versión LTS disponible) y utilizaremos una librería llamada lqip-modern, que nos permitirá crear de forma automática esas versiones reducidas.
Crear un nuevo proyecto
Primero, crea una carpeta en tu equipo (por ejemplo lqip-demo) e inicializa un proyecto de Node.js ejecutando en tu terminal:
npm init -yEste comando generará un archivo package.json con la configuración básica del proyecto.
Contenido del archivo package.json
Importante: Si en tu archivo package.json no existe la propiedad "type", o si tiene el valor commonjs, asegúrate de reemplazarlo por module. Esto es necesario para utilizar código moderno con módulos (ESM) en lugar del antiguo sistema CommonJS.
{ "name": "lqip-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "Felix Icaza", "license": "ISC", "type": "commonjs" "type": "module"}Instalar la dependencia lqip-modern
Ahora instalamos la librería lqip-modern:
npm install lqip-modernEsta herramienta se encargará de analizar tus imágenes y generar una versión en baja resolución codificada en base64, lista para usarse como placeholder.
Generar un placeholder
Crea un archivo index.js con el siguiente contenido:
import lqip from 'lqip-modern';
// Ruta de la imagenconst imagePath = "./image.jpg";
// Generamos el placeholderconst result = await lqip(imagePath);
console.log(result.metadata.dataURIBase64);Y ejecutamos el archivo con el comando:
node lqip.jsObtendrás en la consola una cadena codificada en base64, que representa la versión miniatura de la imagen, similar a esto (una pequeña porción de los cáracteres para no añadirlos todos):
data:image/webp;base64,UklGRlAAAA...Implementar el placeholder con JavaScript
Ahora que ya tenemos nuestra imagen miniatura generada, vamos a implementarla en el sitio web, debemos colocarla donde la necesitemos y además asegurarnos de conocer las dimensiones de la imagen original.
El HTML quedaría así:
<img width="720" height="460" src="data:image/webp;base64,UklGRlAAAA..." data-src="image.jpg" alt="Texto alternativo de la imagen" loading="lazy"/>Si visualizamos el resultado, veremos que carga la miniatura (el placeholder), pero no cambia automáticamente a la imagen original. Para solucionar esto, usaremos un pequeño script en JavaScript en el navegador que reemplace la miniatura por la imagen de alta resolución.
Creamos un archivo, por ejemplo app.js, y lo incluimos en nuestro sitio con el siguiente código:
// Obtenemos todas las imágenes que tengan la propiedad loading="lazy"const images = document.querySelectorAll('img[loading="lazy"]');
// Recorremos el NodeList de las imágenesimages.forEach((image) => { // Asignamos la propiedad data-src a src para cargar la imagen original image.src = image.dataset.src;});Y listo.
Al ingresar al sitio, primero verás la versión miniatura y, unos instantes después, la imagen original en alta calidad.
Además, puedes reutilizar fácilmente esta técnica en todas las páginas de tu sitio: solo necesitas agregar la propiedad loading="lazy", incluir la imagen generada con LQIP en el atributo src y la imagen original en data-src. O automatizarlo de la manera que prefieras para mejorar la DX.
Asi se ve en acción:
Utilizando CSS para implementar el efecto LQIP
Si bien en el ejemplo anterior utilizamos JavaScript para reemplazar la imagen, también es posible lograr este efecto con CSS, además de que podremos utilizar transiciones para un cambio más suave. Esto puede resultar beneficioso en términos de rendimiento y garantizaremos un fallback si el usuario tiene JavaScript deshabilitado.
Para ello, podemos utilizar una estructura HTML como la siguiente:
<picture data-lqip style="--placeholder: url('data:image/webp;base64,UklGRlAAAA...');"> <!-- Imágenes en otros formatos (si lo amerita) --> <source srcset="image.avif" type="image/avif" /> <source srcset="image.webp" type="image/webp" /> <img width="720" height="460" src="image.jpg" alt="Texto alternativo de la imagen" loading="lazy" onload="parentElement.style.setProperty('--z-index', 1), parentElement.style.setProperty('--opacity', 0)" /></picture>Y el CSS correspondiente:
[data-lqip] { --opacity: 1; --z-index: 0;
position: relative; display: inline-block; width: fit-content; height: fit-content;}
[data-lqip]::after { content: ""; inset: 0; width: 100%; height: 100%; position: absolute; pointer-events: none; /* Transición para un cambio suave */ transition: opacity 1s; opacity: var(--opacity); z-index: var(--z-index); background: var(--placeholder); background-size: cover; background-position: 50% 50%;}
[data-lqip] img { z-index: 1; position: relative; overflow: hidden;}
/* Fallback para navegadores que tengan desactivado JavaScript */@media (scripting: none) { [data-lqip] { --opacity: 0; --z-index: 1; }}Así, al cargar la página, el placeholder se mostrará como fondo del contenedor <picture>, y cuando la imagen termine de cargarse, el evento onload cambiará las variables CSS para ocultar el placeholder con una transición suave.
Además con la media query scripting: none, nos aseguramos de que si el usuario tiene JavaScript deshabilitado, el placeholder se oculte automáticamente, mostrando la imagen original sin necesidad de interacción adicional.
Veamos cómo funciona esto en la práctica:
Otras técnicas para generar placeholders
LQIP es una técnica fantástica, pero no es la única. Existen otros métodos para generar placeholders que también pueden mejorar la experiencia visual durante la carga de imágenes, e incluso aportar un toque más creativo al diseño.
Color sólido
Una técnica extremadamente sencilla consiste en usar un color sólido como marcador de posición. Este color suele obtenerse a partir del tono predominante de la imagen original y se aplica directamente mediante CSS, reservando el espacio mientras la imagen completa se carga.
También podemos ir un paso más allá y utilizar degradados para obtener un efecto visual aún más atractivo manteniendo la carga ligera.
SQIP
Otra alternativa es SQIP, una técnica inspirada en LQIP que genera placeholders visualmente más estilizados. En lugar de simplemente mostrar una versión borrosa o de baja calidad o colores, SQIP utiliza ilustraciones vectorizadas con un aspecto artístico, como si fueran imágenes dibujadas o simplificadas.
Este es su repositorio: https://github.com/axe312ger/sqip
Otras herramientas para generar placeholders
Además de lqip-modern, existen otras herramientas y librerías que pueden ayudarte a generar placeholders para tus imágenes:
- BlurHash: Una técnica que genera una representación borrosa de una imagen en forma de cadena corta, ideal para mostrar mientras se carga la imagen completa.
- ThumbHash: Similar a BlurHash, pero optimizado para generar miniaturas compactas y rápidas de cargar.
- Plaiceholder: Una librería que permite generar placeholders de baja calidad, colores dominantes, gradientes y SVGs para imágenes.
- lqip-css: Una herramienta que genera placeholders con CSS para imágenes.
Así mismo muchos frameworks, como Next.js, Astro, Nuxt, entre otros, incluyen componentes que integran la generación de LQIP por si mismos y no tienes que preocuparte en crear tu propia implementación, además de brindar la optimización de imágenes a formatos modernos como WEBP o AVIF. Para Astro existe un componente llamado astro-lqip que facilita la integración de estas técnicas en tus proyectos.