Blog sobre desarrollo WordPress en Español Desarrollo WordPress en Español
lazy load

Lazy load en WordPress para mejorar la velocidad de carga de tu web

Lazy load, carga diferida o carga perezosa es una técnica que consiste en retrasar la carga de ciertos tipos de contenido como imágenes, vídeos y frames.

Evita la carga de objetos que podrían no llegar a utilizarse. Es decir, todo este contenido que se encuentre fuera del viewport o área visible de la web cuando iniciamos la navegación, no será cargado. Sólo se cargará cuando lleguemos a él haciendo scroll.

Si tenemos mucho contenido o por ejemplo una landing page con mucho scroll, aplicar lazy load supondrá una ganancia considerable en el tiempo de carga de nuestra web.

Esta mejora es todavía más notable en dispositivos móviles, ya que el viewport o área visible inicial es menor, por lo tanto más imágenes, vídeos o frames se quedarán fuera en la carga inicial y no serán cargadas a menos que hagamos scroll.

Hace poco he utilizado ésta técnica en este blog y he pasado de estos datos antes de aplicar lazy load (según pingdom tools)

antes de lazy load

a estos otros después de aplicar lazy load:

después de lazy load

Como verás la ganancia ha sido considerable. La home de mi blog ha pasado de cargarse en 979ms, que ya era un gran tiempo, a hacerlo tan sólo en 375ms. Es decir, un pestañeo. Se ha reducido casi a un tercio el tiempo de carga después de aplicar Lazy Load.

La siguiente pregunta es ¿cómo aplico lazy load a mi WordPress? Pues hay dos respuestas: a través de plugins o incorporándolo como funcionalidad imprescindible en tu tema o plugin de utilidades.

Si te decantas por utilizar un plugin te recomiendo que pruebes Lazy Load, Rocket Lazy Load ó a3 Lazy Load.

En caso de querer incorporarlo a mano en la base de tu tema o en tu plugin de utilidades, a continuación te explicaré como lo he hecho yo.

 

Incorporar Lazy Load como funcionalidad imprescindible en tu tema o plugin de utilidades

Lo primero que te diré es que tuve problemas con la librería oficial de jQuery escrita por Mika Tuupola. El problema concreto es que como utilizo bootstrap y tengo un sidebar, ésta librería no me detectaba las imágenes en el sidebar (col-md-3) hasta que llegaba con el scroll hasta el final del contenido principal (col-md-9), porque realmente el sidebar se encuentra por debajo del contenido principal y es con CSS cómo se muestra en un lateral.

Así que hablando con David Navia me recomendó utilizar otra librería, concretamente esta otra de Vincent Voyer. Pero me arrojaba mensajes de error de JavaScript en consola ya que cargo todos los JS en el footer. Funcionar funciona pero no quería ver esos mensajes y tampoco cargar los scripts en el header. Así que indagando un poco más di con LazyLoad – vanilla-lazyload, que me pareció bastante sencilla de implementar y cumplía con los requisitos que buscaba.

Esta librería es JavaScript puro, la ventaja de no ser jQuery es que no es necesario esperar al document ready, por lo tanto actúa más rápidamente cuando hay que mostrar las imágenes que están dentro del área visible de la pantalla en la carga inicial.

En mi caso incorporé Lazy Load a la funcionalidad nativa de mi tema. Para conseguir esto añadí estas líneas en mi functions.php:

function my_lazyload_js() { wp_enqueue_script('jquery_lazy_load', get_stylesheet_directory_uri() . '/js/lazyload.min.js', array('jquery'), ''); } add_action('wp_enqueue_scripts', 'my_lazyload_js'); function my_filter_lazyload($content) { // Don't LazyLoad if the thumbnail is in admin, a feed or a post preview. if ( is_admin() || is_feed() || is_preview() || empty( $content ) ) { return $content; } return preg_replace_callback('/(<\s*img[^>]+)(src\s*=\s*"[^"]+")([^>]+>)/i', 'my_preg_lazyload', $content); } add_filter('the_content', 'my_filter_lazyload', PHP_INT_MAX); add_filter('get_avatar', 'my_filter_lazyload', PHP_INT_MAX); add_filter('widget_text', 'my_filter_lazyload', PHP_INT_MAX); add_filter('get_image_tag', 'my_filter_lazyload', PHP_INT_MAX); add_filter('post_thumbnail_html', 'my_filter_lazyload', PHP_INT_MAX); function my_preg_lazyload($html) { // Reemplazamos src por un pixel en blanco, y la imagen original en un data-attribute $img_replace = $html[1] . ' src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-original' . substr($html[2], 3) . $html[3]; // Para imágenes responsive reemplazamos srcset por un data-attribute $img_replace = preg_replace('/srcset\s*=\s*"/i', 'data-original-set="', $img_replace); // Añadimos una etiqueta noscript con la imagen original para usuarios que tengan desactivado JavaScript $img_replace .= '<noscript>' . $html[0] . '</noscript>'; return $img_replace; }

Haremos la llamada a esta librería de la siguiente manera:

<script type="text/javascript"> var myLazyLoad = new LazyLoad(); </script>

La primera función my_lazyload_js() sirve para encolar el JS que previamente me he descargado de github.

La segunda función, my_filter_lazyload(), es la que utilizo para añadir a los filtros the_content, get_avatar, widget_text, get_image_tag y post_thumbnail_html. Estos filtros devuelven contenidos para mostrar en pantalla.

En función my_filter_lazyload() en un primer paso pregunto si estoy en el admin, en el feed o si el contenido es vacío. En cualquiera de estos escenarios no hacemos nada, en cualquier otro caso utilizo la función preg_replace_callback que llama a my_preg_lazyload() donde se realiza una búsqueda para encontrar las etiquetas <img> y se ejecutan las siguientes acciones:

  • El atributo src de la etiqueta imagen es data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==, o lo que es lo mismo, un pixel en blanco, para que la imagen no pese nada.
  • Añadimos un atributo data-original con la URL de la imagen real.
  • Buscamos si la imagen es responsive y tiene el atributo srcset. En caso afirmativo los sustituimos por data-original-set.
  • Añadimos una etiqueta <noscript> con la imagen original para compatibilizar con navegadores que no tengan activo JavaScript.

 

Resumiendo, lo que hacemos es modificar todas las imágenes, sustituyendo su src por un pixel en blanco, de este modo no pesan nada. El script lo que hace es que todas aquellas imágenes que vayan apareciendo dentro del área visible por el navegador, a través de jQuery sustituye el src por el data-original, que contiene la URL de la imagen. Lo mismo con el atributo data-original-set si la imagen es responsive.

Así sólo cargaremos las imágenes si las utilizamos o dicho de otro modo, sólo si llegamos a ellas haciendo scroll, evitando cargarlas y reducir el peso de la web para el usuario si no llega a ellas.

En la página oficial de esta librería podrás encontrar multitud de ejemplos de integración, así como funcionalidades extras como definir un preloader, aplicar un efecto fadeIn, y extensiones adicionales…

Espero haberme explicado de forma clara, ¿utilizarás LazyLoad a partir de ahora en tus desarrollos?

Puede que también te interese

Añadir un icono personalizado a nuestro custom post type
Añadir un icono personalizado a nuestro custom post type
La versión 3.8 de WordPress trajo consigo nuevas mejoras, el tema Twentyfourteen, y un cambio completo de diseño en el Back End. Con éste cambio,…
Seguridad WordPress: permisos de archivos y carpetas
Seguridad WordPress: permisos de archivos y carpetas
La regla general nos dice que los permisos deben ser 755 para las carpetas y 644 para los archivos. Además recomendable poner el wp-config.php y…
Añadir cabeceras HTTP de seguridad en WordPress
Añadir cabeceras HTTP de seguridad en WordPress
En éste artículo vamos a ver cómo podemos enviar cabeceras HTTP de seguridad en nuestra web. Creo que es algo que no se utiliza mucho,…
Seguridad WordPress: proteger el archivo wp-login.php
Seguridad WordPress: proteger el archivo wp-login.php
En una entrada anterior vimos cómo proteger el acceso a wp-admin. Vamos a ver ahora cómo proteger el archivo wp-login.php, situado en la raíz de…