Rest-Easy icon indicating copy to clipboard operation
Rest-Easy copied to clipboard

Having a menu with tons of items slows down a whole site

Open johndigital opened this issue 5 years ago • 2 comments

This was discovered while working on the new Sesler site, which had a menu with 1400+ items in it.

By default, on every request Rest Easy will query all menus, loop through the menu items, and serialize each menu item into the global siteData: https://github.com/funkhaus/Rest-Easy/blob/master/builders.php#L25-L37

This is to allow theme developers to have quick access to any menus so they can display them on all pages, but we had not taken into account that a site could have thousands of menu items and serializing them could slow a site way down. Sesler was having page load times of about 18 seconds on average.

Normally this wouldn't be a big issue but we use Nested Pages on almost every site which for some reason by default builds out a wp menu to match the structure of the site pages. It's not too uncommon to have a site with 1400 pages, so with Nested Pages doing this automatically it seems likely we will run into this again.

So, we need to find a smart way to stop this from happening in the future. Here are some quick ideas to start with:

  1. In Rest Easy, skip the serialization of any menus that have more than xxx items in them. @SaFrMo pointed out that this feels a bit hacky because we would need to put some hardcoded threshold somewhere of when to skip and when to serialize.
  2. Move the menu serialization out of Rest Easy and into the default rest-easy-filters file in Vuehaus. This is how we have dealt with problematic/dangerous filters in the past.
  3. Add some kind of filter to allow the developer to opt out of menu serialization, possibly conditionally. In this way the developer could build in the logic of option 1 themselves if they want to.

That's about all I can think of, please feel free to add more options. Looking mostly to @SaFrMo and @drewbaker to help out with this decision.

johndigital avatar Dec 03 '18 20:12 johndigital

This is incredible. Good find.

Is it enough to just hardcode in not to auto-include the nested pages menu by default? The fact that it auto makes those “every page menu” is really the only way this is going to come up.

Or we just document this as a gotcha and leave it. Because I do think it’s good the way menus work currently.

drewbaker avatar Dec 03 '18 21:12 drewbaker

I experience the same issue. We have a huge menu containing over 80 items and it gets worse when WPML is activated and duplicates the menus for each translations. To workaround, we commented out menu generation in builders.php and created custom rest endpoints. IMO, the weak point is in serializers/menu.php@35: apply_filters('rez_serialize_object', $element) creates a recursion which is worsen by build_tree function recursive calls.

I used https://gist.github.com/kucrut/efb593d4b263a4b1b6df2549a746a29c to create a tree menu

Nic0tiN avatar Jul 17 '19 10:07 Nic0tiN