lazyload google recaptcha wordpress comment form

Lazy load de Google reCAPTCHA en el formulario de comentarios de WordPress

En el anterior artículo veíamos cómo añadir el reCAPTCHA de Google en el formulario de comentarios de WordPress. En este vamos a ver cómo utilizar la técnica de lazy load para no cargar el reCaptcha a menos que un usuario vaya a realizar un comentario.

¿Por qué implementar una técnica de lazy load en el reCaptcha? En mi caso, la realidad es que un porcentaje muy pequeño de las visitas que tengo acaba dejando un comentario, ronda el 0,001% (si, no es un error). Entonces, ¿por qué cargar el script de Google reCaptcha al 99,999% restante de visitas?

Aunque el script en sí que se encola no pesa mucho (850 B), internamente descarga otro script que pesa 353 kB (137 kB en transferencia) y un CSS de 26 kB. Así que lo ideal sería cargar este script únicamente a los usuarios que realmente interactúen con el formulario de comentarios.

Como suelo decir, la petición más rápida es aquella que no se hace, y en este caso tenemos la «excusa» perfecta para no hacerla.

¿Cómo diferimos la carga del script de reCaptcha?

Una aproximación podría ser detectar cuando un usuario interactúa con el formulario, es decir, hace focus sobre uno de los campos. Esto nos daría a entender que va a comenzar a escribir su nombre, email o mensaje… es aquí donde por medio de JavaScript podemos generar la etiqueta script que haga la petición.

Antes de mostrar el código, recordar que el lazy load para el script de Google reCaptcha que se muestra a continuación está basado en el post anterior, por lo tanto te recomiendo que lo leas para entender cómo adaptamos aquel código para conseguir hacer el lazy load sobre el script.

En el post anterior hacíamos uso del hook comment_form para añadir el script de Google y realizar la validación de los campos por JavaScript. Ahora en el mismo hook, nuestro código quedaría:

<?php

function load_recaptcha_js() {?>
    <script>
        let form = document.getElementById('dwp-comments-form');
        form.removeAttribute('novalidate');

        form.addEventListener('submit', function(e) {
            let comment = form.querySelector('#comment').value;
            let author = form.querySelector('#author').value;
            let email = form.querySelector('#email').value;
            let response = grecaptcha.getResponse();

            if (typeof(comment) == "undefined" || !comment) {
                alert("El mensaje es obligatorio");
                e.preventDefault();
                return;
            }

            if (typeof(author) == "undefined" || !author) {
                alert("Tu nombre es obligatorio");
                e.preventDefault();
                return;
            }

            if (typeof(email) == "undefined" || !email) {
                alert("Tu email es obligatorio (no se publicará)");
                e.preventDefault();
                return;
            }

            if (response.length === 0) {
                alert("Debes validar el ReCaptcha");
                e.preventDefault();
                return;
            }
        });

        function reCaptchaOnFocus() {
            let script = document.createElement('script');
            script.src = 'https://www.google.com/recaptcha/api.js';
            form.appendChild(script);

            document.getElementById('comment').removeEventListener('focus', reCaptchaOnFocus);
            document.getElementById('author').removeEventListener('focus', reCaptchaOnFocus);
            document.getElementById('email').removeEventListener('focus', reCaptchaOnFocus);
        }
        // add initial event listener to the form inputs
        document.getElementById('comment').addEventListener('focus', reCaptchaOnFocus, false);
        document.getElementById('author').addEventListener('focus', reCaptchaOnFocus, false);
        document.getElementById('email').addEventListener('focus', reCaptchaOnFocus, false);
    </script>
<?php }
add_action('comment_form', 'load_recaptcha_js');

La diferencia radica en que hemos eliminado la etiqueta <script src="https://www.google.com/recaptcha/api.js" defer="defer"></script>, y en su lugar añadimos una función llamada reCaptchaOnFocus.

Añadimos esta función como listener al evento focus de los campos comment, author e email. De este modo, cuando un usuario se sitúe sobre uno de estos campos, se disparará la función reCaptchaOnFocus.

Esta función lo que hace es crear una etiqueta script, y establece su atributo src con la URL del script de Google (https://www.google.com/recaptcha/api.js), y la añade a continuación del formulario, lo que hace que se descargue el reCaptcha, y aparezca en su sitio.

Por último se elimina el listener del evento focus, ya que una vez descargado el script no tiene sentido que vuelva a entrar en esta función cuando el usuario cambie de campo.

De este modo logramos que sólo se descargue el script de reCaptcha únicamente cuando el usuario interactúa con el formulario de comentarios, evitando al resto de usuarios (la inmensa mayoría) varias peticiones y varios kB de peso.

En cualquier caso, el rendimiento y velocidad de la página mejora notablemente, ya que aunque el usuario deje un comentario tras leer tu post, hemos eliminado peso y ejecución de JS y CSS de la carga inicial de la página.

¿Te ha resultado útil esta información? 🍺

Si este post te ha resuelto un problema, invítame a un café o a una cerveza. Con este pequeño gesto me animas a seguir escribiendo.

Comentarios

4 comentarios en Lazy load de Google reCAPTCHA en el formulario de comentarios de WordPress

  1. Muchas gracias por este consejo. Tengo una duda, ¿habría alguna forma de utilizar esta función en un formulario de contacto?

    Un saludo y gracias.

    1. Hola Cristian. Si, el formulario de comentarios no deja de ser un formulario. Podrías adaptar la misma función a cualquier tipo de formulario

      1. Genial, muchas gracias. Me lo miraré. Me lo imaginaba pero tenía dudas…También, imagino que he de buscar el ID de formulario y el campo a atacar.
        Muchas gracias.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *:

  • El fin del tratamiento es únicamente la moderación de comentarios para evitar spam
  • La legitimación es tu consentimiento al comentar
  • No se comunicará ningún dato a terceros salvo por obligación legal
  • Tienes derecho al acceso, rectificación y eliminación de los comentarios