# El JavaScript diferido de WP Rocket rompió nuestros formularios

*Activamos el JavaScript diferido para mejorar la puntuación en PageSpeed Insights. Los formularios dejaron de enviarse para todos los visitantes menos para nosotros. No lo detectó ninguna herramienta: nos llamó un cliente.*

Por Aplitec Informàtica, S.L.

Publicado el 30 de septiembre de 2026, 07:17 · Revisado el 30 de septiembre de 2026, 07:17

<https://seomanal.es/tecnico/renderizado/el-javascript-diferido-de-wp-rocket-rompio-nuestros-formularios/>

Estábamos intentando mejorar la puntuación de nuestra web en PageSpeed Insights. Una de las optimizaciones habituales para conseguirlo es diferir la carga del JavaScript, y WP Rocket permite hacerlo fácilmente activando la opción *[Load JavaScript deferred](https://docs.wp-rocket.me/article/1265-load-javascript-deferred)*.

La activamos y, aparentemente, todo funcionaba con normalidad.

Hasta que un cliente nos llamó para decirnos que no podía enviarnos un formulario.

Nosotros entramos en la web, hicimos la prueba y el formulario funcionaba. El problema era que estábamos identificados en WordPress. Al repetirla sin sesión iniciada descubrimos que el fallo afectaba a los visitantes normales de la web, es decir, precisamente a los clientes potenciales.

Detectamos el problema el 1 de septiembre de 2026. No pudimos determinar con exactitud desde cuándo llevaba ocurriendo, así que preferimos no dar una cifra que no pudiéramos confirmar.

## El problema estaba en el orden de los scripts

Después de revisar la carga de JavaScript encontramos la causa.

En la configuración de WP Rocket, la lista de *Excluded JavaScript Files* del diferido contenía `utils.min.js`, mientras que jQuery sí se estaba cargando de forma diferida.

El resultado era que `utils.min.js`, que dependía de jQuery, podía ejecutarse antes de que jQuery estuviera disponible. Cuando eso ocurría, el formulario dejaba de funcionar.

La solución inmediata fue vaciar la lista de exclusiones y comprobar de nuevo el formulario desde una sesión sin autenticar.

Funcionó.

Pero entonces recordamos que no era la primera vez que esta optimización nos daba problemas. Ya habíamos tenido una incidencia con el carrusel de Elementor: `swiper.min.js` se cargaba después del código que intentaba utilizarlo y el carrusel dejaba de funcionar correctamente.

Dos errores diferentes tenían el mismo origen.

Así que decidimos desactivar de forma permanente el JavaScript diferido en todo el sitio. Podíamos seguir añadiendo excepciones fichero por fichero, pero eso convertía cada actualización de WordPress, Elementor o cualquier plugin en una posible nueva rotura.

La puntuación de PageSpeed nos importa, pero un formulario que no permite contactar con nosotros cuesta bastante más que unos puntos en una auditoría.

## Ese mismo día cambiamos también el captcha

Aprovechando la revisión de los formularios decidimos sustituir reCAPTCHA por Cloudflare Turnstile.

En nuestra experiencia, reCAPTCHA se bloquea con relativa frecuencia mediante extensiones de privacidad y bloqueadores de anuncios, por lo que queríamos probar una alternativa que generase menos problemas a los usuarios.

Configuramos Turnstile y, a simple vista, todo parecía correcto.

El widget mostraba «Success» en el navegador.

Dos días después descubrimos que el servidor estaba rechazando las verificaciones.

El motivo era mucho más sencillo: al configurar la integración habíamos copiado la Site Key también en el campo de la Secret Key.

La vista previa de WPForms nos había dado una falsa sensación de seguridad porque permite comprobar que el widget funciona en el navegador, pero eso no significa que la validación completa contra el servidor sea correcta. Cloudflare exige validar la respuesta mediante su [comprobación server-side](https://developers.cloudflare.com/turnstile/get-started/server-side-validation/).

Corregimos la Secret Key e hicimos lo que deberíamos haber hecho desde el principio: enviar un formulario real de principio a fin y comprobar que todo el proceso terminaba correctamente.

Desde entonces, cualquier cambio relacionado con el captcha solo se considera validado después de realizar un envío real.

## No queríamos volver a enterarnos por una llamada

La siguiente pregunta fue bastante evidente: ¿cómo podía ser que un formulario de nuestra propia web estuviera roto y no nos hubiéramos enterado?

Hasta ese momento vigilábamos principalmente el correo de notificación que genera el formulario.

Pero existe un problema con ese enfoque.

Si el formulario falla antes de llegar al punto en el que envía el correo, no se genera ninguna notificación. Desde el punto de vista del sistema de monitorización no ha pasado nada, cuando en realidad un usuario acaba de intentar contactar con nosotros y no ha podido hacerlo.

Necesitábamos vigilar el resultado del formulario, no únicamente el correo posterior.

Por eso añadimos un pequeño sistema de monitorización en el navegador del visitante.

En WPForms escucha las peticiones AJAX mediante `ajaxSend`, `ajaxComplete` y `ajaxError` de jQuery. Si detecta un timeout, una respuesta rechazada, una respuesta que no puede interpretarse correctamente o un error de red, genera una alerta.

Para Contact Form 7 utilizamos sus propios eventos, entre ellos `mailfailed`, `invalid`, `spam` y `timeout`.

Las alertas se integran en el mismo sistema que ya utilizábamos para otros avisos y nos llegan por correo. No hemos creado un canal de monitorización separado únicamente para los formularios.

El objetivo es sencillo: si mañana un formulario deja de funcionar, queremos enterarnos nosotros antes que el cliente.

## Lo que hacemos ahora antes de dar una optimización por buena

Después de estas incidencias hemos cambiado ligeramente nuestra forma de validar los cambios en WordPress.

1. Probamos siempre los formularios sin sesión iniciada y desde una ventana privada. No basta con comprobarlos mientras estamos identificados como administradores.
2. Realizamos un envío real de principio a fin y comprobamos que el mensaje llega correctamente.
3. Vaciamos la caché y repetimos la prueba.
4. Monitorizamos el resultado del envío del formulario, no únicamente el correo de notificación.
5. Y si una optimización empieza a exigir una lista cada vez mayor de excepciones y casos especiales, nos planteamos si la mejora que aporta compensa realmente el riesgo añadido.

PageSpeed Insights es una herramienta útil y mejorar el rendimiento de una web tiene sentido. Pero las métricas dejan de ser útiles cuando una optimización compromete una función crítica.

En nuestro caso, unos puntos menos en PageSpeed son perfectamente asumibles.

Un formulario roto durante días sin que nadie se dé cuenta, no.

## Referencias

1. contactform7.com (2022, 21 de enero). *DOM events*. <https://contactform7.com/dom-events/>
2. developer.mozilla.org (2026, 9 de mayo). *\<script> HTML script element*. <https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script>
3. developers.cloudflare.com (2026, 16 de septiembre). *Validate the token*. <https://developers.cloudflare.com/turnstile/get-started/server-side-validation/>
4. docs.wp-rocket.me (2024, 14 de agosto). *Load JavaScript deferred*. <https://docs.wp-rocket.me/article/1265-load-javascript-deferred>
5. docs.wp-rocket.me (2025, 11 de julio). *Exclude files from Load JavaScript Deferred*. <https://docs.wp-rocket.me/article/976-exclude-files-from-defer-js>
6. docs.wp-rocket.me (2026, 26 de marzo). *User Cache*. <https://docs.wp-rocket.me/article/313-user-cache>
7. docs.wp-rocket.me (2026, 27 de agosto). *How to check if WP Rocket is caching and optimizing your site*. <https://docs.wp-rocket.me/article/46-how-to-check-if-wp-rocket-is-caching-your-pages>
8. Google Search Central (2024, 21 de octubre). *About PageSpeed Insights*. <https://developers.google.com/speed/docs/insights/v5/about>
9. Google Search Central (2025, 10 de diciembre). *Understanding Core Web Vitals and Google search results*. <https://developers.google.com/search/docs/appearance/core-web-vitals>
