WordPress.org

Make WordPress Core

Opened 4 years ago

Last modified 4 years ago

#32474 closed enhancement

Facilitate widgets to be stored in posts instead of options — at Initial Version

Reported by: westonruter Owned by:
Milestone: 4.3 Priority: normal
Severity: normal Version: 2.8
Component: Widgets Keywords: has-patch commit
Focuses: Cc:

Description

Widget instance data has always been stored in wp_options. This worked fine when there were only a few widgets used on a site. When there are hundreds—or thousands—there are big performance problems. When initializing widgets, Core loads the entire settings arrays of all widgets even when they are not used (#23909). Additionally, widget settings options are by default autoloaded: this means that for widget-heavy sites using Memcached Object Cache will reach the 1MB limit and crash since the autoloaded options will no longer be cacheable (WordPress.com even block a site from loading in this scenario). Storage in autoloaded options also means widgets are susceptible to alloptions cache corruption (#31245). Bottom line: widgets stored in options are not scalable.

As I've mentioned elsewhere, widgets should ideally be stored in posts instead of options. In addition to improving the performance problems above, there are many advantaged to storing widgets as posts, including user attribution via post_author, revision history, import/export, querying, widget drafts, scheduled widgets, etc.

Changing the storage mechanism for widgets is a major change, but with a couple small changes to WP_Widget, Core can easily support alternative widget instance storage systems, all through the pre_option_widget_{$id_base} and pre_update_option_{$id_base} filters.

The WP_Widget change is to allow settings to be array-like objects, specifically ArrayIterator. A plugin then can implement the offsetGet() and current() methods for an ArrayIterator subclass to lazy-load data from posts only when it is needed. Otherwise, the only data needed for WordPress at widgets_init are shallow arrays of multi-widget numbers mapped to their corresponding widget instance post IDs. When accessing an item in the array, the offsetGet() method can then look-up the widget instance data and cache it for future lookups.

This backwards-compatible shim approach is similar to what @nacin did in #20103 for WP_Theme (see also How WordPress Evolves Without Breaking Everything).

Let's make the widget a first-class citizen in WordPress.

Change History (1)

Note: See TracTickets for help on using tickets.