Mega Menu causing crash/tab freeze after too many click events

Created on 16 April 2024, 2 months ago
Updated 5 June 2024, 20 days ago

Problem/Motivation

The Better Mega Menu module caused all webform pages to become unresponsive and crash.

Steps to reproduce

It might be hard to reproduce because you'd have to have the full list of modules and versions on our site. We are using Drupal 10.2.5. Perhaps the version of the module I was using was incorrect. If you have Drupal 10.2.5 and The Better Mega Menu 3.0.0-alpha2 or the most recent version installed, you might start to see an issue with webforms.

In our experience, an end user starts filling out the form. The form becomes more and more unresponsive until the page freezes. After about 90 seconds, there is a browser error saying the page is unresponsive.

πŸ› Bug report
Status

Fixed

Version

3.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States rraney

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @rraney
  • πŸ‡ΊπŸ‡ΈUnited States themodularlab

    Are you seeing any errors drupal watchdog or other php logs? If so can you share them? Are you only seeing issues with the mega menu when using webforms or is it occurring on other pages without webforms? I would also suggest upgrading to https://www.drupal.org/project/tb_megamenu/releases/3.0.0-alpha4 β†’ .

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    I am seeing this php error.
    Symfony\Component\HttpKernel\Exception\HttpException: The specified #ajax callback is empty or not callable. in Drupal\Core\Form\FormAjaxResponseBuilder->buildResponse() (line 67 of /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php).

    I should say that I removed our captcha form field and the problem persisted. I also turned off Ajax, and completely refreshed cache in Drupal and browser, and the problem persisted. I never turned off Honeypot to see if that was the conflict.

    It did feel like an Ajax type of issue, which seem to be utterly inexplicable.

    I believe the issue happened on Mega Menu alpha4, then I downgraded to alpha2, and it still was a problem.

  • πŸ‡ΊπŸ‡ΈUnited States themodularlab

    And this is only occurring on pages using webform? In a non-production environment, what happens if you exclude the TB Megamenu block from a page that is experiencing the issue? Some ajax is used on the megamenu admin builder ui, but not really for rendering on a page on the front-end.

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    The reason I am pinpointing this module is because the most recent change I made was adding the module. I started getting reports of issues. I simply started working backwards to see what may have caused it. When I uninstalled the module, there were no more issues with the webform. I wonder if there might be a conflict with a module used by webform.

    I will start doing more troubleshooting in my development environment. I'll try excluding the block from the webform page. I'll try different versions of the module. I'll try uninstalling honeypot and captcha modules. I will test other non-webform type pages.

    Thanks for your initial questions which help me figure out how to troubleshoot locally and in dev.

  • πŸ‡ΊπŸ‡ΈUnited States themodularlab

    No problem. I'll leave this issue open in case others encounter this issue and/or you can find some more concrete evidence that this is a bug in TB Megamenu.

    Just out of curiosity, since you said you recently added this module, do you have at least one menu item added and have saved the mega menu builder? There's another issue in the issue queue ( https://www.drupal.org/project/tb_megamenu/issues/3291741 πŸ’¬ TB MegaMenu error: Post was missing the following information: menu_config Active ) where some folks narrowed it down to rendering a megamenu without any items in the menu.

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    Yes I have items. It was working in production and I've reverted back to the old menu.

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    I cloned our production site to development less than 2 days ago. The site should be exactly what it was when I reported this issue. However, I noticed on development that the module is using version alpha2, while production is on alpha4. I am not having the issue on the development site, which is confounding.

    I decided to try upgrading the module in development. I noticed it upgrade the field_hidden module from 2.1.0 to 2.1.1. Is this a required module for TBM? Interestingly, this module is still at 2.1.0 in production while the TBM module has been upgraded there.

    I cleared cached and did some testing. I was unable to recreate the problem in development. Currently in development, the TBM module is alpha4 and the field_hidden module is 2.1.1.

    I decided to try upgrading field_hidden module to 2.1.1 in production, reinstall TBM and replace the menu block, then test again. Since I uninstalled the module (which I probably shouldn't have done), my menu is now not working. I'll have to spend time trying to get it to work again before I know anything more.

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    I got the Mega Menu working again. I went to the webform and tested it. The same issue as reported was there. I do not understand why it's working okay in test/dev but not in production. They should be almost identical. I'm going to have to think about what might be happening here. Again, the TBM module versions are the same - alpha4. The field_hidden modules are also the same.

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    I'm in a cPanel environment, not using git yet. So when I clone production to development, it actually doesn't do everything. I've noticed that I also have to manually copy the libraries folder. It also doesn't clone the root folder above /web, so I have to manually copy vendors (and composer files, etc.). The only thing I can think of right now is there might be a library or extension that is different in production right now which is possibly used by Mega Menu. I'd like to know all the dependencies for this module.

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    So sorry - I just noticed that the alpha4 module in development didn't successfully update. I'm running both of these commands in composer and it's not updating the module:
    composer require 'drupal/tb_megamenu:^3.0@alpha'
    composer require 'drupal/tb_megamenu:3.0.0-alpha4'

    It says "nothing to remove or update". When I clear cache, the module still shows alpha2 being used in production.

    I'm going to try to downgrade the module in production and test the form again.

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    Voila. I downgraded to alpha2 and the issue has gone away! Now we're getting somewhere. Something that was changed in alpha3 or 4 is causing our issue, it seems.

    Here are some of our modules which are definitely or possibly associated with webform:
    honeypot
    field_hidden
    conditional_fields
    webform_attachment
    honeypot
    field_permissions
    field_ui
    captcha
    recaptcha
    recaptcha_v3

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    There were no logged errors this morning when I did testing. However, here's a full trace for an error found on this page yesterday.

    Type	php
    Date	Tuesday, April 16, 2024 - 11:55
    User	Anonymous (not verified)
    Location	https://www.douglascountyks.org/form/court-records-request?_wrapper_format=drupal_ajax&ajax_form=1
    Referrer	https://www.douglascountyks.org/form/court-records-request
    Message	Symfony\Component\HttpKernel\Exception\HttpException: The specified #ajax callback is empty or not callable. in Drupal\Core\Form\FormAjaxResponseBuilder->buildResponse() (line 67 of /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php).
    Severity	Error
    Hostname	172.59.74.243
    Operations	
    Backtrace	
    #0 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php(112): Drupal\Core\Form\FormAjaxResponseBuilder->buildResponse(Object(Symfony\Component\HttpFoundation\Request), Array, Object(Drupal\Core\Form\FormState), Array)
    #1 [internal function]: Drupal\Core\Form\EventSubscriber\FormAjaxSubscriber->onException(Object(Symfony\Component\HttpKernel\Event\ExceptionEvent), 'kernel.exceptio...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
    #2 /home/limestonedouglas/public_html/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\ExceptionEvent), 'kernel.exceptio...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
    #3 /home/limestonedouglas/public_html/vendor/symfony/http-kernel/HttpKernel.php(239): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\ExceptionEvent), 'kernel.exceptio...')
    #4 /home/limestonedouglas/public_html/vendor/symfony/http-kernel/HttpKernel.php(91): Symfony\Component\HttpKernel\HttpKernel->handleThrowable(Object(Drupal\Core\Form\FormAjaxException), Object(Symfony\Component\HttpFoundation\Request), 1)
    #5 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #6 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #7 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #8 /home/limestonedouglas/public_html/web/core/modules/big_pipe/src/StackMiddleware/ContentLength.php(32): Drupal\Core\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #9 /home/limestonedouglas/public_html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #10 /home/limestonedouglas/public_html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #11 /home/limestonedouglas/public_html/web/core/modules/ban/src/BanMiddleware.php(50): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #12 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\ban\BanMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #13 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #14 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #15 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #16 /home/limestonedouglas/public_html/web/core/lib/Drupal/Core/DrupalKernel.php(704): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
    #17 /home/limestonedouglas/public_html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
    #18 {main}
  • πŸ‡©πŸ‡ͺGermany LAKdev

    We don't have webform installed but the error occurs on any form after firering too many click events, i. e. editing a lot of textfields or check/uncheck checkboxes several times.

    Here's how to reproduce the error:

    1. Upgrading tb_megamenu to alpha4
    2. Open a form. On Firefox it is enough to check and uncheck a checkbox several times until the tab gets slower and then completely freezes. On Chrome I needed to edit a lot of textfields until the tab also freezed.
    3. CPU usage of tb_megamenu/dist/js/frontend.js skyrocketed

    I found out that this commit https://git.drupalcode.org/project/tb_megamenu/-/commit/a90a1c892369945a... is causing the issue. After commentig the following code in plugin.js out and running yarn build, everything works again:

    // Anytime there's a click outside a desktop menu that has arrows, close the menu.
        document.addEventListener('click', event => {
          if (!event.target.closest('.tbm') && !this.isMobile && this.hasArrows) {
            this.closeMenu();
          }
        });
  • πŸ‡ΊπŸ‡ΈUnited States rraney

    That's great you isolated the issue. The code seems like it should have a conditional
    // Anytime the menu is open && there's a click outside the menu, close the menu

  • πŸ‡ΊπŸ‡ΈUnited States dasginganinja Bethlehem, PA

    I can confirm that there are event listeners getting added on each click event for things not in the TB Megamenu. It seems that more and more of these listeners keep getting added as well and that causes a linear/exponential amount of work to stack up, causing the page to become unresponsive.

    This click event should be faster. Maybe the handleTouch() function needs some love so we don't get all of these defined?

  • First commit to issue fork.
  • Status changed to Needs review 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States KurtTrowbridge

    We also ran into this problem, just as described in #16 (whenever a click event is triggered; you don't even have to click on interactive elements, though things like forms and accordions that require user interaction are naturally where it's most obvious), while running alpha3. Downgrading to alpha2 fixed the issue.

    Based on the suggestion in #15, I provided an MR that tracks whether or not the menu is open, and adjusted the JavaScript in two problematic places so closeMenu() is only called if the menu isn't currently open. (I also snuck in a minor typo fix.) This appears to be working for us, but additional reviews/suggestions are much appreciated. Thanks!

    If credited, please also credit my coworker joshcavindergmailcom β†’ , who helped me troubleshoot.

  • Status changed to RTBC about 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States dasginganinja Bethlehem, PA

    I can confirm that the changes in #19 in MR !88 were able to resolve our issues on our site.

    --- on a sidenote:
    That nvmrc is WAY outdated @ Node 10...

  • πŸ‡ΊπŸ‡ΈUnited States rraney

    I upgraded the module in my test environment. Then I replaced code using the MR!18. I tested my webform after flushing cache. I do not have the same issue as before. I cannot confirm that the menu is actually working at this time. I am having issues with the dropdowns regardless of the module version, but regarding this issue, the merge request is working for me.

  • Status changed to Needs work about 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States rraney
  • Status changed to Needs review about 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States rraney
  • πŸ‡ΊπŸ‡ΈUnited States rraney

    My apologies. In my deployment to production, I missed a step apparently. I tried a second time and it's now working in production. I don't want to change the status again since I'm not a collaborator for this module. If you feel it's been tested enough, feel free to change it back to "tested". Again, sorry but thanks for everyone's assistance.

  • Status changed to RTBC about 1 month ago
  • πŸ‡¬πŸ‡§United Kingdom Hebl

    Hey,

    I can also confirm that the changes in #19 and MR !88 fixed this issue for our case.

    Changing status to RTBC.

    Thanks to @KurtTrowbridge for your work on this.

  • First commit to issue fork.
  • πŸ‡³πŸ‡ΏNew Zealand fraserthompson Dunedin, New Zealand

    MR !88 solves the problem, but doesn't address the root cause. There are also numerous other issues with event listeners in this release.

    Multiple identical document level event listeners are being added more than once, which may or may not effect performance, but in any case is bad practice. Even if we check for the menu being open before trying to close it, it still adds an event listener unnecessarily every time the menu is closed. It also adds event listeners multiple times for each menu link.

    The above merge request should fix all of this.

  • First commit to issue fork.
  • Status changed to Needs review about 1 month ago
  • πŸ‡ΊπŸ‡ΈUnited States knaffles

    @ fraserthompson - Thanks for your work fixing those event listeners. I made one additional change so that `isOpen` is set to true if/when the user opens the mobile menu by clicking the mobile toggle button. Otherwise, the clicks/focus outside of the menu only result in a closure on mobile if one of the submenus has already been opened.

  • Status changed to Fixed about 1 month ago
  • πŸ‡ΊπŸ‡ΈUnited States knaffles

    MR #90 has been merged.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.69.0 2024