Mantys Core
Mantys CorePerformance guideCluster: JavaScript5 minJuly 15, 2026

¿Por qué mi menú de hamburguesa solo se abre al segundo clic?

En una frase: si activó un retraso de JavaScript (cargar los scripts en el primer clic o tras un temporizador), el primer toque en la hamburguesa despierta la carga del script, no abre el menú. El menú solo responde al segundo toque. La solución: aislar el script del menú y sus dependencias fuera del retraso, o mejor aún, darle un menú vanilla sin dependencias.

Toca la hamburguesa: nada. Toca de nuevo: el menú se abre. Cada vez, se necesitan dos toques. No es aleatorio ni un fallo del tema: es el comportamiento mecánico del “retraso de JavaScript”, una optimización muy habitual. He aquí el porqué, y las dos formas de solucionarlo.

Qué hace el “retraso de JavaScript” (y por qué se pierde el primer clic)

Para ganar puntos de rendimiento, el “retraso de JS” (o “carga en interacción”) pospone la ejecución de los scripts hasta que el visitante hace algo: un scroll, un movimiento del ratón o un primer toque. Mientras nadie se mueva, no se ejecuta ningún JavaScript, y la puntuación inicial sube.

El problema es evidente en cuanto se piensa en ello: el primerísimo toque en la hamburguesa ES esa primera interacción. Así que ese toque no abre el menú, sino que desencadena la carga de los scripts. Para cuando llegan y se adjuntan al botón, su dedo ya se ha ido. El menú solo se abre en el segundo toque, cuando el script por fin está ahí y escuchando.

Toque 1 → nada

  • El toque se “consume” para lanzar la carga del script, no para abrir el menú.

Toque 2 → el menú se abre

  • Los scripts por fin han cargado y el manejador ya está escuchando en el botón.

Es aún más visible con una variante de temporizador: si los scripts cargan “después de 3 segundos”, un visitante que toca antes se encuentra con una hamburguesa muerta.

Key infos
  • El retraso de JS espera una primera interacción (o un temporizador) antes de cargar los scripts.

  • El primer toque en la hamburguesa se “consume” para iniciar esa carga, no para abrir el menú.

  • De ahí el síntoma constante: el menú solo responde al segundo toque.

Confirme que es esto (30 segundos)

Tres comprobaciones sencillas:

  • El síntoma es constante, no intermitente: es siempre dos toques. Un fallo real sería más errático.
  • Pestaña Network de DevTools: recargue, no toque nada, y observe. Los scripts del menú (a menudo jQuery + el script del tema) solo se descargan después de su primera interacción. Esa es la firma del retraso.
  • Prueba de eliminación: desactive temporalmente el retraso de JS. Si la hamburguesa responde al primer toque, el culpable queda identificado.

Solución A: aislar el menú Y sus dependencias

La reacción natural es excluir el script del menú del retraso. Eso es necesario, pero a menudo no basta, y aquí es donde la mayoría se atasca.

Un menú de tema casi nunca funciona solo: depende de otros scripts, normalmente jQuery (y a veces jQuery Migrate, o el núcleo del tema). Si excluye el script del menú pero deja jQuery en el retraso, el script del menú se ejecuta cuando jQuery aún no existe: falla silenciosamente o no se adjunta a nada. Resultado: el menú sigue roto, y usted no entiende por qué, ya que “el menú está excluido”.

Así que hay que excluir toda la cadena: jQuery → (jQuery Migrate) → el script del menú. Juntos.

Dos trampas concretas al declarar estas exclusiones:

  • Apunte a un fragmento único de la URL del archivo (por ejemplo jquery.min.js o el nombre del script del tema), no por su “handle” interno: según la herramienta, el sufijo técnico puede eliminarse y la exclusión falla su objetivo.
  • Mantenga una comprobación sobre el estado del documento: el script excluido debe tolerar ejecutarse pronto (comprobar que el DOM está listo antes de adjuntarse al botón).

La contrapartida que hay que aceptar: al sacar jQuery y el menú del retraso, usted recarga parte del JavaScript antes de tiempo, por lo que pierde parte de la ganancia de rendimiento. Es aceptable si quiere conservar el menú del tema tal cual, pero no es gratis.

Key infos
  • Excluir solo el script del menú no basta: depende de jQuery.

  • Excluya toda la cadena (jQuery + el script del menú), o el menú se rompe “excluido pero muerto”.

  • Apunte por un fragmento único de la URL, no por el handle; y el script excluido debe tolerar la carga temprana.

  • Contrapartida: recargar jQuery antes de tiempo cuesta parte de la ganancia de rendimiento.

Solución B (el mejor caso): un menú vanilla, sin dependencias

La solución real y duradera, sobre todo en un tema pesado (Divi, por ejemplo, donde es el menú el que obliga a cargar jQuery), es dejar de hacer que el menú dependa de jQuery.

Un menú de hamburguesa, en el fondo, es trivial: un botón que alterna una clase en la navegación. Bastan unas pocas líneas de JavaScript nativo, sin ninguna dependencia:

HTML + JS vanilla
<button class="nav-toggle" aria-expanded="false" aria-controls="site-nav">Menu</button>
<nav id="site-nav" class="site-nav"><!-- links --></nav>

<script>
  const btn = document.querySelector('.nav-toggle');
  const nav = document.getElementById('site-nav');
  btn.addEventListener('click', function () {
    const open = nav.classList.toggle('is-open');
    btn.setAttribute('aria-expanded', open);
  });
</script>

Como este script es diminuto y sin dependencias, se abren dos opciones:

  • lo incluye tal cual en línea, sin diferir, en el tema: la hamburguesa responde al primer toque, siempre;
  • y entonces puede diferir absolutamente todo lo demás en su JavaScript con total tranquilidad, ya que la única interacción crítica (abrir el menú) ya no depende de nada.

Una ventaja nada desdeñable: en muchos temas, el menú es la única razón por la que jQuery carga con prioridad. Un menú vanilla puede por tanto permitirle sacar jQuery de la ruta crítica por completo. Es lo mejor de ambos mundos: un menú instantáneo y un JavaScript más ligero.

Key infos
  • Una hamburguesa = un botón que alterna una clase: unas pocas líneas de vanilla, cero dependencias.

  • En línea y sin diferir, responde al primer toque, y puede diferir todo lo demás con tranquilidad.

  • A menudo, incluso le permite sacar jQuery de la ruta crítica. El mejor caso.

Con Mantys Core

Con Mantys Core

Mantys Core gestiona ambas vías con precisión. Para la solución A, sus excepciones de retraso se declaran por un fragmento de URL (no por el handle frágil) y tienen en cuenta la cadena de dependencias, con la comprobación de estado del documento que hace que la exclusión realmente funcione en lugar de fallar en silencio.

Y para la solución B, el enfoque de “bloque autosuficiente, no diferido” es nativo: un menú vanilla puede servirse fuera del retraso mientras todo el resto del JavaScript se pospone, sin que usted tenga que hacer malabares entre puntuación y funcionalidad.

Dicho de otro modo: tanto si conserva el menú del tema como si pasa a vanilla, la hamburguesa responde al primer toque, sin sacrificar el adelgazamiento del resto.

En resumen

  • El “segundo clic obligatorio” viene del retraso de JS: el primer toque despierta la carga del script en lugar de abrir el menú.
  • Confírmelo observando que los scripts solo cargan después de la primera interacción (o desactivando el retraso).
  • Solución A: excluya del retraso el menú Y sus dependencias (jQuery incluido), apuntando por URL, con una comprobación de estado. Funciona, pero cuesta parte de la ganancia.
  • Solución B (el mejor caso): un menú vanilla sin dependencias, incluido en línea y sin diferir, que responde al primer toque y le permite diferir todo lo demás, jQuery incluido.
Mi cuentaObtener licencia →