Indexar imágenes en Google usando Lazy Load

Publicado el 23 de diciembre del 2018 por Lino Uruñuela


Desde hace unos años estamos viviendo y siendo protagonistas de un cambio de paradigma en el mundo SEO, en mi opinión es el cambio más importante desde al menos una década, estamos pasando de conectarnos desde ordenadores a conectarnos a través del móvil, y esto también impulsa que cada vez más se pase del HTML a JavaSccript.

Aquí hemos hablado mucho de cómo Google indexa determinado contenido cargado mediante JavaScript, cómo rastrea e indexa el contenido en dos fases u olas, dónde en la primera ola de indexación obtiene el HTML sin renderizar el DOM y cómo en la segunda ola de indexación Google sí ejecuta e interpreta JavaScript.

Hoy vamos a probar distintas maneras de cargar las imágenes mediante lazy-load (cargar las imágenes, una vez se haya descargado el resto de HTML), para mejorar el tiempo de carga del contenido y por ende, mejorar la experiencia de nuestros usaurios.

Técnicamente, maneras de hacer esto hay muchas, pero no todas ellas son aconsejables desde el punto de vista SEO, ya que si no lo haces correctamente Google no verá esas imágenes, no las indexará y no se posicionarán. En este experimento vamos a intentar averiguar si algunos métodos son o no son válidos para SEO.

No queremos entrar en hacer lazy load al hacer scroll, Google no realizará scroll por lo que para este artículo no nos interesa. Nos centraremos en cómo cargar unas cuantas imágenes usando lazy load y que sean indexables por Google. Hay documentación muy buena del propio Google en la que explica muy bien cçomo usar la API intersection observer de Chrome, con unos ejemplos muy sencillos para los que quieran profundizar...

¿Qué es lazy load?

En HTML la manera de insertar una imagen es básicamente de la siguiente manera

<img  alt="alt de la imagen" src="url-imagen">




Cuando el navegador rendedriza (pinta en nuestra pantalla) el HTML devuelto por el servidor, al llegar a este tag descargará la imagen y mientras lo hace no sigue renderizando el resto de contenido, es decir, el usuario tiene que espera a la descarga de la imagen para ver el resto de contenido empeorando su experiencia de navegación, sobretodo en dispositivos móviles dónde las capacidades de los dispositivos y de la conexión hacen que estos detalles sean relevantes.

Para subsanar esto podemos hacer que la imagen se cargue y se "pinte" una vez descargado todo el HTML, esto creo que todos lo tenemos claro, pero debemos entrar al detalle, técnicamente hablando, para saber cómo es la manera correcta de hacerlo.

Un ejemplo de cómo cargar imágenes medidante lazy load

Imaginemos que tenemos en medio de nuestro HTML un <div id="contendor"> en el cual va la imagen

<div id="contendor">
<img  alt="alt de la imagen" src="url-imagen" id="imagen-final">
</div>



Una opción que podemos hacer es añadir la imagen a ese contenedor usando Java Script una vez se haya cargado la página, por ejemplo

<div id="contendor">    </div> 




Y con js una vez se haya cargado el resto de HTML

$(document).ready(function(){
window.document.getElementById ("contendor").innerHTML = '<img  alt="alt de la imagen" src="url-imagen" id="imagen-final">';
} );


Pero si lo realizamos de esta manera, cuando se carga el HTML el usuario de primeras no verá ni sabrá que ahí va una imagen hasta que se cargue el HTML despúes se descargará la imagen y una vez descargada en el navegador se pinta mediante javasctipt.

Esto puede causar una muy mala experiencia de usuario porue al no respetarse el espacio que debe ocupar la imagen en la pantalla, cuando se añada la imagen mediante Java Script hará que cambie el ltamaño del documento, y si por ejemplo el usario ha hecho scroll, de repente verá que el contenido se desplazará y si estabas leyendo posiblemente tengas que hacer scroll para volver a situarte en el punto por dónde ibas. Por ejemplo se ve mucho en sitios que cargan la publi de esta manera.

Cargar miniatura de posición

Para evitar esto, podemos usar un "truco" que es cargar una miniatura de la imagen (thubmnail) , o incluso un pixel transparente, con el ancho y alto de la imagen final, y después, con JavaScript  sustituirla por la imagen final, la cual ponemos en el atributo src-lazy de la imagen, creo que me explico mejor con código.

<div id="contendor">
<img  alt="alt de la imagen" width="300px"  height="200px" src="url-thubmnail" src-lazy="url-imagen" id="imagen-final">
</div>
....
//este código JavaScript cargará la imagen que haya en el campo src-lazy
window.document.getElementById("imagen-final").src = window.document.getElementById("imagen-final").getAttribute("src-lazy");



El problema de hacerlo así es que Google indexará la imagen en miniatura y no la imagen final, esto sucede porque Google solo indexará las imágenes que vayan en una etiqueta <img y un atributo src, me lo confirmó el propio John Mueller, así que cómo estamos viendo, usar lazy load tiene sus cosillas y hay que saber hacerlo bien, o puede ser un desastre SEO.

Con esta explicacion espero que hayais comprendido las dudas de cómo hacer lazy load de tal manera que Google indexe la imagen final y no la miniatura, y además, si no molestamos al usuario al insertar las imágenes mejor que mejor.

Usar <noscript>  y miniatura de posición

Para ir un paso más allá ahora vamos a intentar que Google indexe la imagen que quermeos, para ello solo tenemos que añadir  al código anterior un <noscript> y el HTML de la imagen original, algo así

<div id="contendor">
  <img  alt="alt de la imagen" src="url-thubmnail" src-lazy="url-imagen" id="imagen-final">
</div>
<noscript>
<img  alt="alt de la imagen" src="url-imagen" id="imagen-final">
</noscript>
window.document.getElementById("imagen-final").src = window.document.getElementById ("imagen-final").getAttribute ("src-lazy");

La etiqueta <noscript>solo la interpretan los navegadores que no ejecutan java script, por ejemplo Googlebot (en su primera ola de indexación). En cuanto a SEO esta podría ser la solución más sencilla y eficaz, aunque tiene un PERO.

Los usuarios que naveguen con javascript desactivado verán la imagen que está dentro del <noscript> pero también verán la imagen en miniatura. es decir, verán ambas imágenes, lo que hará de ello una mala experiencia de navegación .

Añadir estilos para eliminar <noscript>

Para subsanar esto podedmos usar algún truco con los estilos, por ejemplo tener un estilo que oculte la miniatura si no tiene javascript habilitado. Para ello debemos añdir al tag <html> un estilo, y a las imágenes cargadas por lazy load otro que luego serán desabilitads mediante java script en los navegadores que sí ejecutan javascript mientras que lo s que no lo ejecutan lo tendrán habilitado y por tanto ocultará todas  las miniaturas

<html class="no-js"> ..
 <style> .no-js .lazy { display: none; } </style>
 <img class="lazy" alt="alt de la imagen" src="url-thubmnail" src-lazy="url-imagen" id="imagen-final">
 <noscript>
   <img alt="alt de la imagen" src="url-imagen">
 </noscript>
 ......
 window.document.getElementById ("imagen-final").src = window.document.getElementById ("imagen-final").getAttribute ("src-lazy"); window.document.documentElement.classList.remove ("no-lazy");




Cómo aegurarnos que las imágenes serán indexables

Ahora sí podríamso decir que solventamos todos los problemas,

  1. Añadimos, además'del src, otro atributo a las imágenes para la imagen final
    En el atributo src pondremos la imagen en miniatura que cargará muy ràpido debido a sus pequeñas dimensiones, incluso podrías usar un pixel transparente.
    En el nuevo atributo indicaremos la url de la imagen final que cargaremos y que queremos indexar. Después, mediante javascript interccambiaremos el valor de ambos y la imagen final reemplazará al thubmnail.
     
  2. Usamos thubmnail de posición
    Imagen en miniatura, por ejemplo si la imagen original es de 500px de ancho y 300 de altp podríamos crear una miniatura de 50px de ancho y 30 de alto.

    Una vez creada la imagen, definimos con width y height el tamaño original, para que el usuario vea que hay habrá una imagen y que no se desplace el contenido cuando carguemos la imagen final. 
  3. Añadimos <noscript>
    Para asegurarnos que Google verá la imagen sí o sí.
  4. Creamos un estilo que  oculta las imagenes en miniatura
    Esto ocurrirá solamente en los navegadores que no tienen JavaScript, ya que estos usuarios verán la imagen que tenemos en <noscript>
  5. Eliminamos ese estilo con JavaScript
    Por lo que solamente se ocultarán las imágenes en <noscript> de los navegadores que ejecuten JavaScript

Otras recomendaciones

Cuanto más caminos le demos a Google tanto para rastrear y descubrir las imágenes cómo el darle contexto y significado, mucho mejor. Dos acciones típicas y que debemos añadir son usar microformatos y también añadirlas al sitemap.

  1. Añadir datos estructurados
    Es muy conveniente que además de realizar los pasos anteriores también se añadan datos estructurados (acordes al tipo de contenido que sea, news, producto, etc), de esta manera añadimos otra camino para que Google rastree, indexe y posicione< las imágenes.
  2. Añadir imágenes a sitemaps
    De la misma manera es una muy buena práctica el añadir las imágens a nuestros sitemaps, y así ofrecer a Google diversos camisnos para que encuentre nuestras imágenes


¿Cómo saber si Google lo carga correctamente?


Este es uno de los putnos más conflictivos,ya que dependiendo de qué herramieta uses (todas del propio Google, pero ninguna coincide.
Por ejemplo si en el viejo Google Search Console, usamos la opcion de "Rastrear como Google" vemos lo siguiente.

Indexar imágenes e Google usando Lazy Load, Rastrear como Google (GSC)

Es decir, no parece que esté cargando las imágenes mediante Lazy Load, pero posiblemente lo haga más adelante.

En el caso del viejo Google Search Console, cuando ejecutamos la prueba podemos ver mediante los logs del servidor cómo sí está accediendo a todas las imágenes, tanto las que hemos puesto inicialmente en el atributo src (las miniaturas) como las imágenes finales que están en el atributo src-lazy 

Logs lazy load



Prueba de optimización para móviles
En este caso vemos como el contenido que también incluimos mediante javascript lo está cargando bien, no así las imágenes, parece que no fuese capaz de verlas, pero tal y como hemos dicho antes, esto lo hará en la segunda ola de indexación, y no nos ofrece la representación de  cómo se verásn las imágenes, pero estoy casi seguro que las verá sin probleas, tal y como hace desde e viejo search console.

Indexar imágenes e Google usando Lazy Load,

Experimento con  Lazy Load

A continuación muestro el experimento para ver cómo indexar imágenes cargadas  en Google usando Lazy Load. En esta url hay diferentes imágenes cargadas con diferentes técnicas, usando src data-src src-lazy, con <noscript>

Por ejemplo Google seguramente termine por interpretar el valor de data-src (yo he usado src-lazy para vero más claro) ya que se está estandarizando, pero siempre es mejor hacerlo de la manera más escrupulosa posible.

He utilizado ajax básico, quiere decir que he creado la carga de las imágenes usando XMLHttpRequest, compatible con la mayoría de navegadores. dependiendo de que otros métodos usemos podrían no ser compatibles, recordar que de momento Google usa la versión 41 de Chrome para renderizar las páginas, por lo que muchos métodos de carga de contennido mediante jQuery como fetch podrían no ser accesibes, Google de momento solo es compatible con las especificaciones ECMAScript 5 de JavaScript.

Pasados unos días o unas semansa podremos ir comprobando los resultados. Estas pruebas también las estoy haciendo en otro site, para comprobar que ocurre lo mismo.

No sé si he conseguido explicarlo bien, espero que sí, y cuallquier duda no dudéis en preguntar, si puede ser en los comentarios del blog, ya que así las opiniones, dudas y sugerencias están en e mismo sitio que el experimento y otros usuarios que lean el blog puedan aprovecharse tambiénn de ello :)

Los diferentes métodos que estamos probando

  • Carga normal, sin lazy load
  • Imagen usando thubmnail de posición
  • Cargar imagen desde desde data-src
  • Imagen usando thubmnail de posici&oacute;n y noscript
  • Sin usar thubmnail pero s&iacute; noscript
  • Sin usar thubmnail ni tampoco noscript
  • Con thubmnail tama&ntilde;o mediano + tama&ntilde;o grande v&iacute;a lazy load

Aquí el experimento con la carga de imágenes Lazy Load, si véis el código podéis comprobar que es bastante sencillo.


 


Francisco Morales (@)hace Hace más de 5 años y 71 días

Lino muy interesante las distintas formas de cargar la imagen. Pero no crees que lo realmente interesante de aplicar Lazy Loading es cargar únicamente lo que se está viendo en pantalla.

En tu experimento, por ejemplo, se carga todo el contenido cuando solo estoy viendo de entrada el texto inicial y una parte de la primera foto.

Salud

Lino Uruñuela (@)hace Hace más de 5 años y 70 días

Completamente de acuerdo :)

Pero en este experimento solo quería comprobar el método usado para hacer lazy load, en este caso con xmlhttp, y con las opciones de thumbnail y demás y luego ya aplicarlo con la lógica necesaria.

Para lo que comentas, en la documentación de Google que enlazo explican cómo hacerlo tal cómo dices, con
IntersectionObserver’s, no la he probado, pero tiene muy buena pinta :)

Emirodgar (@)hace Hace más de 5 años y 23 días

Muy interesante el experimento. Yo estaba probando con los nuevos formatos webp y pero al final, como eran pocas imágenes y usaba Masonry, decidí cargarlas de golpe y olvidarme de la carga secuencial. Con tu experimento he podido responder a algunas de las preguntas que tenía ;)

Lino Urnuela (@)hace Hace más de 5 años y 23 días

@Emirodgar gracias!

Pero parece que en tema de imágenes las pilla lo hagas cómo lo hagas parece, eso sí, siempre que no tengas un fallo serio en JavaScript.

rubiel taborda (@)hace Hace más de 3 años y 351 días

hola amigo, he usado el plugins Lazy Load y la velocidad de la pagina ha mejorado muchom, creo que es una buena solucion, mas cuando es una pagina de clasificados, por que la verdad estas paginas suben muchas imagenes, si alguno pudiera darme un mejor concejo para mejorar lo resibo con gratitud.


Últimos posts

Últimos comentarios


JaviLazaro
Ya me has dado la necesidad de crear un comaando en bash para hacer estas cosas. Gracias Lino por estos tips
Post: Obtener KWs de varias fuentes usando la línea de comandos

Señor Muñoz
Lino, el 11% más de clicks y el 47% más de impresiones diarias ¿es algo constante o depende de cada sitio web?
Post: Diferencias entre la exportación de datos de Search Console usando BigQuery o usando la API

Carlos
Hola En mi blog tengo artículos atemporales (es decir, no caducan nunca, de manera que sirve para quien lo lea hoy o lo lea dentro de 5
Post: Tratamiento de urls que tienen un tiempo de vida muy corto

Profe Ray
Veo que hay comentarios de hace 5 años y de hace 3 años. ¿Habrá algun post actualizado sobre este tema o sigue funcionando? Lo cierto es
Post: Cómo cargar css y js y no bloquear la carga de contenido

Pepe
Muchas gracias por el articulo!! Muy buena información.
Post: Qué es ofuscar enlaces y cómo mejora el enlazado interno

María
Sí, he buscado el archivo robots.txt y todo está correcto. La última versión vista con error fue el 08/11/2021 y la última vez que el
Post: Errores críticos originados por el robots.txt

Lino
@María un placer verte por aquí :) Lo primero, a veces, con el robots.txt no se puede "forzar" a que lo rastree, si tu site no es muy p
Post: Errores críticos originados por el robots.txt

María
Hola Lino, tengo el mismo problema. El probador de robots de google me indica: "Error al obtener el archivo robots.txt Tienes un archivo ro
Post: Errores críticos originados por el robots.txt

Mario
Estoy tratando de vincular los datos en Google Data Studio y he combinado los datos de la tabla "Impresión del sitio" con "Impresión de UR
Post: Datos incoherentes y cálculo de la posición media en Search Console

José B. Moreno Suárez
Yo hace tiempo que agrupaba con stemmers. Ahora, además, comparo con un proceso las keywords que aportan impresiones a una URL determinada
Post: Clustering de keywords SEO en Google Search Console - Parte II