Make WordPress Core

Opened 11 years ago

Last modified 5 years ago

#23909 new defect (bug)

Widgets settings loaded and instances registered unnecessarily

Reported by: alex-ye's profile alex-ye Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.5.1
Component: Widgets Keywords: needs-patch
Focuses: Cc:

Description (last modified by westonruter)

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)

#1 follow-up: @nacin
11 years ago

Could you please provide the queries and the debug backtrace for them?

#2 in reply to: ↑ 1 @alex-ye
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 @ryanduff
10 years ago

Here's a screenshot in Genesis. 7 queries on a sidebar-less homepage.

http://d.pr/i/1iD5

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 @ryanduff
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 @ryanduff
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 @westonruter
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 @westonruter
9 years ago

  • Description modified (diff)
  • Summary changed from Widgets Settings Loaded When No-Needed to Widgets settings loaded and instances registered unnecessarily

#8 @westonruter
8 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).

Note: See TracTickets for help on using tickets.