#32769 closed defect (bug) (fixed)
Customizer Menus: Setting sanitization innefficiencies resulting in severe performance slowdowns
Reported by: | westonruter | Owned by: | westonruter |
---|---|---|---|
Milestone: | 4.3 | Priority: | high |
Severity: | normal | Version: | 4.3 |
Component: | Customize | Keywords: | has-patch commit |
Focuses: | performance | Cc: |
Description
I have an install with 1,383 nav menu items across multiple menus. I did an Xdebug profiling of loading customize.php
and I saw ~50k+ calls to _wp_json_sanity_check
being made, and the time to load the customizer with Xdebug profiling was ~13 minutes. When I then disabled Menu Customizer and re-ran profiling and the number of _wp_json_sanity_check
calls went down to ~3k, and the time dropped to ~1.5 minutes.
The issue is probably closely related to #32103, and the solution may be found in what I've worked on specifically for widgets: https://github.com/xwp/wp-customize-widgets-plus/blob/0.2/php/class-efficient-multidimensional-setting-sanitizing.php
Attachments (4)
Change History (20)
#3
@
9 years ago
This was also reported in early menu customizer plugin testing at https://wordpress.org/support/topic/large-menu-systems-problems-saving?replies=3
This ticket was mentioned in Slack in #core-customize by sheri. View the logs.
9 years ago
#5
@
9 years ago
I don't think we could get away with lazy-loading settings data as needed (assuming that would be an ajax call). With controls/the UI side it's usually easily handled within the time it takes the animation to complete, and scales seemingly linearly with the number of menu items as the controls are rendered from the template and inserted into the DOM. An ajax call would be much slower, so I'd want to see if we can find a good way to only do that if a menu is more than say 50 items.
But 50k calls to the same function definitely sound wrong, and would probably be the better approach to fixing.
This ticket was mentioned in Slack in #core-customize by sheri. View the logs.
9 years ago
This ticket was mentioned in Slack in #core by westonruter. View the logs.
9 years ago
#9
@
9 years ago
I'm still doing analysis on the underlying cause, but if lazy loading of the settings is the route we go with, then #28580 would largely encapsulate the solution.
#10
@
9 years ago
It looks like the main reason for the inefficiencies is that wp_setup_nav_menu_item()
is getting called multiple times, and with each call it makes several get_post_meta()
calls, so the number of post meta calls quickly multiply. The first thing I'm working on is making this more efficient to only call wp_setup_nav_menu_item()
and get the required postmeta once.
#11
@
9 years ago
- Keywords has-patch needs-testing added; needs-patch removed
I have implemented the change to reduce the redundant calls to wp_setup_nav_menu_item()
, and in doing so eliminating a large number of postmeta lookups, in all resulting in about a ~200% speed boost. See 32769.diff.
The more in depth solution, lazy loading the settings and controls when the sections are expanded, will drastically reduce the load time yet again.
#12
@
9 years ago
@celloexpressions Can you give this patch a try and see how it impacts performance when you have the hundreds of menu items in your test install, as I believe you do?
#13
@
9 years ago
It seems qualitatively better with the patch. Note that there were a couple merge conflicts with the docs changes in the setting class. Unless you see any red flags, I'd commit this (fixing the merge issue), given the quantitative improvements you found.
We should probably wait on lazy-loading settings for a future release, and pair that change with UI adjustments that make the animation smoother and potentially show loading indicators while settings are loaded. Note that the controls are already lazy-loaded for menu items, which is very effective (it typically takes 2-3 seconds to load my massive 350-item menu, which happens when you open that menu, not when you open the Customizer). I think I put a patch to do the same for all controls on #28580, but I'd like to do #30738 and #30741 before making that change, as those tickets would result in small performance improvements that could be magnified in terms of actual UI speed when all controls and settings are lazy-loaded on an as-needed basis. Could probably be done in 4.4.
One thing that would greatly improve initial load time is to lazy-load the
nav_menu_item
settings for a givennav_menu
when the menu is actually expanded.