WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.5k stars 4.2k forks source link

Navigation Block: Mobile menu javascript won't work till page is fully loaded #41149

Open jordesign opened 2 years ago

jordesign commented 2 years ago

Description

The Mobile/Hamburger menu button is not working properly when the site is slow to load.

I expected: to be able to use the mobile menu before the page and assets are fully loaded.

What Happened: mobile menu button was blocked from working until the page (and third-party scripts) were fully loaded.

Step-by-step reproduction instructions

  1. Set up a site with a navigation block.
  2. Set up a page which is likely to load slowly. A great way to do this is by including embeds to third parties (like Youtube or Facebook) or scripts which pull in Ads from third parties
  3. Load the page on a mobile device - and try to immediately use the menu/hamburger button.

Screenshots, screen recording, code snippet

No response

Environment info

WP 5.9.3

Happens with GB deactivated, and also with GB 13.2.1 active

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

luisherranz commented 2 years ago

The hydration is happening on the load event:

https://github.com/WordPress/gutenberg/blob/fdd079b845e7e6a9f9338b46f38a8ca168b1e5d2/packages/block-library/src/navigation/view.js#L36-L38

It's necessary for sites that load the scripts before the HTML. Moving this script to the footer will probably make this unnecessary, and therefore the hydration will occur faster. However, it is still not ideal since this script (and any other like it) should be loaded asynchronously to avoid blocking the main thread while the browser is finishing the HTML/CSS rendering.

I think the only solution that would make sense in the long term is to delay the hydration as much as possible in the main thread (using an async script + requestIdleCallback hydration) but capture the click event. If the user clicks before the hydration, it still works (with a delay, but it works).

This is what Qwik is doing for all the event listeners, but I've also seen it in the Rocket hydration techniques, so maybe we can get some inspiration from there. There's a proposal for supporting this natively, which is promising.

Do you have any other idea @jordesign?

A bit off-topic, but we are investigating how to add Partytown to WordPress, which will remove the load of third-party scripts in the main thread.

EDIT: Yesterday, I proposed the async/defer functionality in https://github.com/WordPress/gutenberg/issues/41236#issuecomment-1134758794, and I've just added the onClick hydration technique to the Block Hydration Experiments tasks.