Opened 11 years ago
Last modified 5 years ago
#23909 new defect (bug)
Widgets settings loaded and instances registered unnecessarily
Reported by: | alex-ye | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 3.5.1 |
Component: | Widgets | Keywords: | needs-patch |
Focuses: | Cc: |
Description (last modified by )
The settings for all registered multi-widgets get loaded with each request in widgets_init
, and all widgets get registered even if they are never used (e.g. inactive ones). As the total number of inactive widgets tend to grow over time, the result is slower and slower page loads across all of a WordPress install.
Ideally only the widgets returned by wp_get_sidebars_widget()
would only get loaded and registered, though this would have an impact on how the widgets in the Customizer work.
Change History (8)
#2
in reply to:
↑ 1
@
11 years ago
- Cc nashwan.doaqan@… added
Replying to nacin:
Could you please provide the queries and the debug backtrace for them?
I will, but it's easy to debug, as you know WordPress register the widgets in the 'init' hook during the registering, it get all widgets settings !
It's not only in the back-end also in the front-end (even if you don't call any sidebar) as I checked .. I am thinking if we can change this be behave to get widget settings lately ( only when needed ) .
anyway I will attach some queries and tests when I get time :)
#3
@
10 years ago
Here's a screenshot in Genesis. 7 queries on a sidebar-less homepage.
Also checked some default themes and got similar results. 5 calls in Twenty Fourteen, and 4 in Twenty Twelve.
The first 4 seem to be consistent, and the difference in number is what's registered additionally by the theme. Twenty Fourteen registers 1 widget (so 5 total) and Genesis registers 3 (giving 7 total).
Maybe it has something to do with how/when those are registered compared to some other core widgets. Or maybe they have something else in common that I'm missing.
#4
@
10 years ago
Seems to somehow be tied to inactive widgets. Clearing them and deleting the widget_* rows in the options table now gets me a matching number of calls to matching number of registered widgets.
#5
@
10 years ago
Did some more digging. Not tied to inactive widgets, but rather unregistered widgets. Core adds a few widgets to the sidebar on install which gets them an entry in the DB. _register_widgets() then excludes them from the _register() call which is what is triggering the get_option() as noted in the backtrace (image in ryanduff).
So... on a clean install if no widgets were added to a sidebar, you'd actually be adding about 12 db queries, not including whatever the current theme is registering.
This looks to be any widget that has never been added to a sidebar, so the number of queries will vary from site to site.
I'm still trying to grok the WP_Widget class internals, but it looks like it may only need to do this if the widget is actually registered in a sidebar and not global, at least on the front end. If you're in admin or customizer, it still needs to instantiate the widget from the looks of things.
#6
@
9 years ago
Related: #26876
And as I noted there, I think it would be ideal for performance reasons if widgets were only registered if they are active for the current context, i.e. after sidebars_widgets
has been filtered or when dynamic_sidebar
is called. I'm working on a site that has hundreds of widgets, maybe thousands when factoring in inactive widgets, and yet only a dozen are actually used on a given page.
#7
@
9 years ago
- Description modified (diff)
- Summary changed from Widgets Settings Loaded When No-Needed to Widgets settings loaded and instances registered unnecessarily
#8
@
9 years ago
The Customize Widgets Plus plugin has a module “Optimized Widget Registration” which limits the number of widgets registered to the current request. More work would need to be done here for widgets in the Customizer, specifically on implementing including lazy-loading widgets that are present in the preview (#28580) and implementing JS-driven widgets (#33507).
Could you please provide the queries and the debug backtrace for them?