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.
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,
- 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.
- 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.
- Añadimos <noscript>
Para asegurarnos que Google verá la imagen sí o sí.
- 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>
- 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.
- 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.
- 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.
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
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.
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ón y noscript
-
Sin usar thubmnail pero sí noscript
-
Sin usar thubmnail ni tampoco noscript
-
Con thubmnail tamaño mediano + tamaño grande vía lazy load
Francisco Morales (@)hace Hace más de 5 años y 336 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 335 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 288 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 288 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 4 años y 251 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.