Make WordPress Core

Opened 7 years ago

Closed 5 years ago

#42558 closed enhancement (wontfix)

Reduce the number of capability checks performed by the Customizer

Reported by: johnbillion's profile johnbillion Owned by: johnbillion's profile johnbillion
Milestone: Priority: normal
Severity: normal Version:
Component: Customize Keywords: has-patch needs-testing
Focuses: performance Cc:


On a vanilla installation of WordPress running the Twenty Seventeen theme, the Customizer performs over 400 user capability checks via current_user_can().

The majority of these are duplicate checks performed for each customizer setting. This includes:

  • ~140 calls to current_user_can( 'customize' )
  • ~220 calls to current_user_can( 'edit_theme_options' )
  • ~20 calls to current_user_can( 'manage_options' )

The main offenders are:

  • WP_Customize_Manager->unsanitized_post_values()
  • WP_Customize_Setting->check_capabilities()
  • WP_Customize_Section->check_capabilities()
  • WP_Customize_Panel->check_capabilities()

Calls to current_user_can() are quite cheap, but they're certainly not free, especially on sites which have filters hooked onto the map_meta_cap and user_has_cap filters, and sites with extra Customizer controls registered.

With a static property cache in each of the WP_Customize_Manager, WP_Customize_Section, and WP_Customize_Setting classes, the 400 capability checks are reduced to fewer than 30.

Patch coming up soon, after some more testing.

Attachments (1)

42558.patch (4.7 KB) - added by johnbillion 7 years ago.

Download all attachments as: .zip

Change History (11)

#1 @johnbillion
7 years ago

  • Owner set to johnbillion
  • Status changed from new to accepted

#2 @westonruter
7 years ago

Related: a setting's sanitize and validate methods currently get called every time that its dirty value is read. If a given changeset (post) value for a setting hasn't changed, then the value returned should be whatever was previously sanitized/validated. This could yield a much higher performance improvement than reducing the cap checks. See #41271.

Some previous work on caching was done in #32103.

#3 @westonruter
7 years ago

  • Milestone changed from Awaiting Review to 5.0

7 years ago

#4 @johnbillion
7 years ago

  • Keywords has-patch needs-testing added; needs-patch removed

42558.patch is a first pass at a patch.

#5 @westonruter
7 years ago

@johnbillion why static?

#6 @johnbillion
7 years ago

The property is static so its value is shared between instances. This means the value is set once per class instead of once per instance.

#7 @westonruter
7 years ago

@johnbillion yes I know, but use it here? None (almost) of the other member vars are static. Using static makes it harder to unit test. Maybe too there also there could be a case where you want to instantiate WP_Customize_Manager and other classes later with another current user active, but the the caps in the static var could leak to other such Customizer sessions.

#8 @westonruter
7 years ago

What if there was a new $wp_customize->current_user_can() method that all of the customizer classes could then call as part of their manager? Then they wouldn't need to store their own caches of the cap checks, as the manager could have common set shared by all for that instance.

#9 @johnbillion
6 years ago

  • Milestone changed from 5.0 to Future Release

#10 @johnbillion
5 years ago

  • Milestone Future Release deleted
  • Resolution set to wontfix
  • Status changed from accepted to closed

Closing due to lack of interest. It's not a big enough problem to worry about.

Note: See TracTickets for help on using tickets.