La carga diferida o lazy loading es una de las técnicas de optimización web de cara al WPO y mejora en las métricas web principales más utilizada, y de hecho de las que más sentido tiene.
Básicamente se trata de no cargar ninguna imagen, iframe, vídeo, mientras que el usuario no llegue navegando a su ubicación, cargándose poco a poco, a medida que el visitante hace scroll por la página.
Esto hace que el navegador no tenga que descargar recursos que igual no va a ser necesario mostrar, con la consiguiente mejora en tiempos de carga y ahorro de recursos del navegador, dispositivo e incluso del servidor.
Vamos, que es una técnica genial, que por si no lo sabías WordPress ya incorpora de serie, de manera nativa.
Índice de contenidos
¿Por qué debería de desactivar el lazy loading si es tan genial?
Pues mira tú por donde, resulta que hay ocasiones en las que querrás controlar, incluso desactivar, la carga diferida de medios, de algún medio, o de algún medio en según qué página, situación, etc.
Además, también te vas a encontrar en ocasiones que Google PageSpeed te va a mostrar como errores que afectan al LCP imágenes en el primer doblado (above the fold) con lazy loading, que se solucionan quitándoles el atributo de carga diferida.
¿Por qué es esto así? Pues, dicho brevemente, porque el lazy loading ralentiza la carga de ese recurso, y eso hace que la carga de tu página sea – simplemente – más lenta, al menos en esa primera parte, en ese above the fold.
Esto es lo que vamos a aprender hoy, a controlar selectivamente la carga diferida o lazy load.
Nota: Salvo que diga lo contrario, todos los códigos PHP que voy a compartir deben añadirse, preferentemente, a un plugin propio de personalizaciones o, en su defecto, al archivo functions.php del tema hijo activo
Desactivar lazy loading nativo de WordPress del todo
Lo primero, nada selectivo, pero que debes conocer, es que puedes desactivar del todo la carga diferida nativa de WordPress.
Aunque parezca que no tiene nada que ver con el objetivo de esta guía tiene todo el sentido, pues a veces, es mejor activar y gestionar la carga diferida con plugins, y para ello el primer paso – si no lo hace el plugin – es desactivar el lazy loading nativo de WordPress.
El código es este:
/* Desactivar lazy loading nativo de WP */ add_filter( 'wp_lazy_loading_enabled', '__return_false' );
Si lo prefieres, también puedes desactivarlo con plugins como este o este otro.
Desactivar lazy loading por ID y tamaño
Empezando a personalizar selectivamente la carga diferida, un primer enfoque sería desactivar el lazy loading para ciertos medios (imágenes, etc.) indicando su ID y el tamaño.
El código sería como el de este ejemplo:
/* Desactivar carga diferida por ID de imagen y tamaño */ function ayudawp_sin_carga_diferida_id( $value, $image, $context ) { if ( 'the_content' === $context ) { $image_url = wp_get_attachment_image_url( 4532, 'large' ); // Cambia el ID y tamaño del adjunto if ( false !== strpos( $image, ' src="' . $image_url . '"' )) { return false; } } return $value; } add_filter( 'wp_img_tag_add_loading_attr', 'ayudawp_sin_carga_diferida_id', 10, 3 );
En este caso desactivamos la imagen con ID 4532
en su tamaño grande (large
)
Desactivar lazy loading en la primera imagen
Atendiendo a lo que comentaba al principio de esta guía, del problema que detecta Google PageSpeed en cuanto al lazy loading en la métrica LCP, un modo de solucionarlo es desactivar el lazy loading en la primera imagen de la página que se esté visitando.
Esta puede ser la imagen de un carrusel, la imagen destacada de una entrada o página, o simplemente la primera imagen del contenido.
Habría varias maneras de hacerlo, dependiendo de cómo tengas activa la carga diferida…
Sin plugins
Si no usas plugins o quieres un código con el que desactivar la carga diferida de la primera imagen en WordPress puedes usar este código:
/* Quitar lazy load de primera imagen */ function add_responsive_class($content){ if ( is_single() || is_page() || is_front_page() || is_home() ) { $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8"); $document = new DOMDocument(); libxml_use_internal_errors(true); $document->loadHTML(utf8_decode($content)); $imgs = $document->getElementsByTagName('img'); $img = $imgs[0]; if ($imgs[0] == 1) { // Comprobamos primero si es la primera imagen del contenido $img->removeAttribute( 'loading' ); $html = $document->saveHTML(); return $html; } else { return $content; } } else { return $content; } } add_filter ('the_content', 'add_responsive_class');
Con Autoptimize
Si usas el lazy loading de este plugin tendrías que añadir este código para desactivarlo de la primera imagen de la página, sea la que sea:
/* Desactivar lazy load de Autopimize de la primera imagen */ add_filter( 'eio_lazy_fold', function( $count ) { return 1; });
Si, por algún motivo, no funciona es posible porque la primera imagen no sea la del contenido, sino por ejemplo el logo de la cabecera, en cuyo caso puedes probar a cambiar return 1
por return 2
para desactivar la carga diferida en las primeras 2 imágenes, no solo en la primera.
Otro método que ofrecen los desarrolladores del plugin es con este otro código:
add_filter( 'autoptimize_filter_imgopt_lazyload_from_nth', function(){return 1;});
De nuevo, puedes cambiar la cantidad de imágenes cambiando el return 1
por return 2
para la dos primeras, return 3
para las tres primeras y así sucesivamente.
Y, por último, si lo prefieres, puedes hacerlo desde la misma interfaz del plugin, indicando el número de imágenes que quieres excluir.
Con WP Rocket
Si usas el fantástico plugin WP Rocket las posibilidades se amplían, y mucho.
Pero, de momento, aquí tienes el código para desactivar la primera imagen si usas la carga diferida de WP Rocket:
/* Desactivar lazy load en primera imagen con WP Rocket */ function add_responsive_class($content){ if ( is_single() || is_page() || is_front_page() || is_home() ) { $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8"); $document = new DOMDocument(); libxml_use_internal_errors(true); $document->loadHTML(utf8_decode($content)); $imgs = $document->getElementsByTagName('img'); $img = $imgs[0]; if ($imgs[0] == 1) { // Comprobamos primero si es la primera imagen del contenido $img->setAttribute('class','alignnone size-full remove-lazy'); $html = $document->saveHTML(); return $html; } else { return $content; } } else { return $content; } } add_filter ('the_content', 'add_responsive_class'); function rocket_lazyload_exclude_class( $attributes ) { $attributes[] = 'class="alignnone size-full remove-lazy"'; return $attributes; } add_filter( 'rocket_lazyload_excluded_attributes', 'rocket_lazyload_exclude_class' );
Si prefieres no hacerlo con códigos, WP Rocket te ofrece otras maneras de excluir la primera imagen, o la que sea. El truco está en añadir el identificador CSS de la imagen en la caja de exclusiones de los ajustes de LazyLoad del plugin.
En la caja puedes incluir la clase CSS, el nombre de archivo de la imagen o iframe, como prefieras. Si optas por aplicar la exclusión a una clase CSS puedes identificarla haciendo clic derecho e inspeccionar en el navegador para mostrarla en las herramientas de desarrollo del navegador.
Como ya te habrás percatado, esta caja de exclusión no solo te va a servir para desactivar el lazy loading de la primera imagen de las entradas o páginas, sino que, mediante la exclusión por clase CSS puedes aplicar la carga diferida selectiva a más medios, da igual dónde estén.
Con SG Optimizer
También con el plugin de optimización de SiteGround, SG Optimizer, puedes excluir la primera imagen, o la que sea, de la carga diferida. De nuevo, puedes hacerlo de 2 maneras.
Por un lado, simplemente añadiendo la clase CSS en la caja de exclusiones de la carga diferida.
O, si lo prefieres, con un código como este:
/* Excluir clases CSS de lazy load con SG Optimizer */ add_filter( 'sgo_lazy_load_exclude_classes', 'exclude_image_from_lazy_load' ); function exclude_image_from_lazy_load($classes) { $classes[] = 'nombre_clase_1'; $classes[] = 'nombre_clase_2'; return $classes; }
Solo tienes que sustituir los nombres de las clases de ejemplo por las que quieras excluir.
Desactivar lazy loading en otras partes
Visto el caso particular de desactivación del lazy loading en la primera imagen, importante para evitar errores en la lectura LCP de las métricas web principales, vamos a ver cómo desactivar la carga diferida en otros recursos.
Con WP Rocket
Este plugin, como suele ser habitual, permite todo tipo de operaciones, como también excluir cualquier medio añadiendo en la caja de exclusiones de lazy loading su clase CSS o incluso el nombre del archivo, realmente sencillo.
Desactivar lazy load en entradas concretas
¿Quieres desactivar el lazy load en entradas o páginas concretas, no hay mucho misterio. Con WP Rocket encontrarás en el editor una caja de ajustes desde la que activar o desactivar cualquier optimización general.
Ahora bien, si prefieres usar códigos también es posible, aquí tienes unos cuantos…
Desactivar lazy load en imágenes destacadas
Un código muy práctico sería desactivar el lazy loading en las imágenes destacadas, así:
function rocket_lazyload_exclude_src( $src ) { $featured_img_url = get_the_post_thumbnail_url(get_the_ID(),'medium_large'); if ($featured_img_url) { $src[] = $featured_img_url; } return $src; } add_filter( 'rocket_lazyload_excluded_src', 'rocket_lazyload_exclude_src' );
Desactivar lazy load en entradas individuales
Con este código desactivarás la carga diferida en entradas, pero se mantiene en páginas y en el archivo del blog:
add_filter( 'wp', '__deactivate_rocket_lazyload_if_page' ); function __deactivate_rocket_lazyload_if_page() { if ( is_single() ) { add_filter( 'do_rocket_lazyload', '__return_false' ); } }
Desactivar lazy load en todas las entradas
Con este código desactivas la carga diferida en las entradas pero no en las páginas:
add_filter( 'wp', '__deactivate_rocket_lazyload_if_page' ); function __deactivate_rocket_lazyload_if_page() { if ( is_page() ) { add_filter( 'do_rocket_lazyload', '__return_false' ); } }
Desactivar lazy load en página del blog
Si prefieres no tener carga diferida en el archivo de entradas, en el blog, el código es este otro:
add_filter( 'wp', '__deactivate_rocket_lazyload_if_page' ); function __deactivate_rocket_lazyload_if_page() { if ( is_home() ) { add_filter( 'do_rocket_lazyload', '__return_false' ); } }
Desactivar lazy load en portada
Con este otro código desactivas la carga diferida en la página de inicio de tu web:
add_filter( 'wp', '__deactivate_rocket_lazyload_if_page' ); function __deactivate_rocket_lazyload_if_page() { if ( is_front_page() ) { add_filter( 'do_rocket_lazyload', '__return_false' ); } }
Desactivar lazy load según el nombre del archivo
¿Tienes varias imágenes con nombre similar que quieres excluir de la carga diferida? Mira qué código más apañado para excluir todas las que contengan cierto texto en el nombre de archivo:
function rocket_lazyload_exclude_src( $src ) { $src[] = 'nombre-incompleto-imagen-que-uso-mucho'; return $src; } add_filter( 'rocket_lazyload_excluded_src', 'rocket_lazyload_exclude_src' );
Desactivar lazy load por el origen de la imagen
Un uso interesante sería poder excluir imágenes de la carga diferida según el dominio de origen, por ejemplo:
function rocket_lazyload_exclude_src( $src ) { $src[] = 'wp.com'; //Excluir de lazy load toda imagen servida desde wp.com return $src; } add_filter( 'rocket_lazyload_excluded_src', 'rocket_lazyload_exclude_src' );
En el ejemplo anterior excluimos del lazy load toda imagen servida desde el dominio wp.com
, el utilizado normalmente por Jetpack para servir imágenes desde su CDN o las miniaturas de las entradas relacionadas.
Desactivar lazy load para los gravatares
Si no quieres carga diferida en los avatares de Gravatar.com el código a añadir será este:
remove_filter( 'get_avatar', 'rocket_lazyload_images', PHP_INT_MAX );
Desactivar lazy load en clases CSS con código
Para terminar, si prefieres un código para desactivar la carga diferida en ciertas clases CSS el código sería así:
function rocket_lazyload_exclude_class( $attributes ) { $attributes[] = 'class="clase-css-a-excluir"'; //Cambiar a la clase a excluir del lazy load return $attributes; } add_filter( 'rocket_lazyload_excluded_attributes', 'rocket_lazyload_exclude_class' );
Con Autoptimize
En el plugin Autoptimize vamos a encontrar una caja de exclusión, en la que igual que con WP Rocket, podemos incluir clases CSS o nombres de archivo. Sencillo y efectivo.
Con SG Optimizer
Termino con SG Optimizer pues es el plugin que creo que ofrece la mejor solución para una activación/desactivación selectiva de la carga diferida, al ser totalmente opcional, mediante sencillos selectores.
Simplemente activa o desactiva dónde quieras aplicar la carga selectiva:
- Imágenes (por defecto)
- Iframes
- Vídeos
- Gravatares
- Miniaturas
- Imágenes adaptables (responsive)
- Widgets
- Para móviles
- En shortcodes
Además de la posibilidad de excluir clases CSS en la caja de exclusión, como vimos antes.
Me parece el modo perfecto de abordar esta necesidad.
¿Te gustó este artículo? ¡Ni te imaginas lo que te estás perdiendo en YouTube!
Hola Fernando. Utilizo «a3 Lazy Load». Compartes un código para desactivar el lazy loading nativo de WordPress, si no lo hace el plugin… Sería de sentido común que todo plugin de lazy load desactive el nativo… ¿pero cómo puedo saber si lo hace o no?
Compartes otro código para desactivar lazy loading por ID ¿Cómo puedo saber el id de una imagen?
El código para no aplicar lazy load en la primera imagen es interesante para mí, pues tengo una imagen de cabecera en todas las páginas y entradas… Lo he añadido al plugin de personalizaciones, pero en la etiqueta sigue añadiendo loading=»lazy»
He añadido el código en functions.php del tema hijo, y me ha tumbado el Sitio…
Gracias.
Hola Jose,
Todos los plugins que conozco desactivan el lazy nativo.
Los ID de los adjuntos se localizan igual que los de las entradas, pasa el cursor sobre una imagen en la biblioteca de medios y abajo en la url sale el número, o edítala y en la url te sale.
He probado el código en varios sitios de prueba y no me ha roto nada, pero cada instalación es un mundo :/
Gracias Fernando… El código para desactivar lazy loading por ID también provoca un error fatal… En la línea return $value; el editor me indica: Syntax error, unexpected T_RETURN
Pero he descubierto una forma de hacerlo mediante «a3 Lazy Load», que en la sección de ajustes – carga diferida de imágenes, ofrece la opción de excluir imágenes introduciendo los nombres de clase de las imágenes. He visto en el codigo fuente que las imágenes tienen la clase wp-image-id
En la etiqueta img sigue habiendo un loading=»lazy», sin embargo ya no aparece el resto de código aplicado por el plugin para la carga diferida, como src=»//dominio/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif» data-lazy-type=»image» y después todo el código entre las etiquetas «noscript», por lo que supongo que funciona…
Salud.
Vaya, genial, gracias por compartir con todos tu experiencia 🙂
Hola!, En SiteGround, con SG Optimize, ¿hay que desactivar antes el lazy load nativo de WP? Saludos!
No, lo hace el plugin ya cuando activas su herramienta de lazy load 😉
Hola. Gracias por el tutorial. Muy bueno (como siempre, bah! 🙂
Dicho esto te comento el siguiente problema que tienen los códigos que mandaste:
1) Cuando utilizo el código global (Para quitar lazyload a la 1ra. imagen de todas las entradas), lo que ocurre es que, me aparece un error cada vez que quiero editar (*)
(*) Aclaración; Estoy usando Elementor pero SOLO en la home. Para el resto de las entradas y páginas uso el editor de Wordpress.
2) Cuando uso el codigo por ID, en el function NO me deja colocar el argumento del tamaño (‘large’ o el que sea).
Le quito dicho argumento (porque total a mi, me «conviene» que cualquier medida de la imagen destacada NO cargue en diferido) y el function me lo toma. Peeero…
3) Solo para UNA imagen por ID (Es decir que me «elimina» el lazyload de la 1er. imagen cuyo ID coloco en, $image_url = wp_get_attachment_image_url(15402, 15398, 15502); // Colocar el ID de la imagen
Ergo. Si quiero copiar el mismo codigo pero con cada ID, el function me lo «rechaza» porque dice que, el argumento
function ayudawp_sin_carga_diferida_id… ¡YA se utilizó en una linea anterior, je!
¿Que puedo hacer?
Aguardo tus comentarios.
Desde ya, muchas gracias.
Saludos.
Hola Fernando, te felicito por tu gran labor.
Una cuestión más difícil de resolver…., utilizo el plugin perfmatters y tengo un problema con la carga diferida Lazy Load, a ver si me puedes echar una mano. No consigo inhabilitar Lazy Load en las páginas de categorías. A ver si me explico mejor…., cuando entras a mi web y por ejemplo vas a cualquier categoria de producto…bueno pues, en lo widgets laterales tienes filtros, puedes filtrar por modelo, por marca, por precio etc.., pero cuando tiras de estos filtros las imágenes de los productos e incluso de las etiquetas no aparecen, para que aparezcan tienes que recargar la página.
Me gustaría a ser posible marcar una regla para que Lazy Load no cargue cuando se realiza una busqueda.
Nota: los widgets que tengo para filtros no son los que lleva por defecto woocommerce. Tengo el plugin Product search, que permite la búsqueda predictiva.
Gracias de antemano
Hola Tomás, pues con Perfmatters no he probado pero seguro que tiene filtros para desactivar el lazy load por clases CSS
Hola!
usando SG Optimizer que usa la clase skip-lazy para no hacer el lazy load en las imágenes que lleven esa clase, me encuentro con el problema de que en Elementor no se puede asignar esa clase a la imagen del above the fold, porque tanto si usas un widget de imagen como uno tipo cta por ejemplo que incluye una imagen,… si asignas en Elementor esa clase css la asigna a un previo, no al .
¿Sabes de alguna forma con la que asignar la clase skip-lazy en la imagen del above the fold usando elementor?
Saludos!
Se me ocurre algo más fácil, y es asignarle al elemento above-the-fold una clase CSS inexistente, con el nombre que sea, y luego excluirla en el SG Optimizer 😉
Veo que se eliminó las etiquetas HTML q puse en mi pregunta,… Decía que si asignas en Elementor esa clase css la asigna a un “div” previo, no al “img”.
El problema es ese, cómo asigno la clase css? Porque si la asignas en “Avanzado” del widget de Elementor, NO la asigna al img y por tanto SG Optimizer lo ignora,… (lo asigna a un “div” previo donde dentro estará el “img”).