[wp-trac] [WordPress Trac] #41271: Customizer sanitize_callback gets called multiple times on setting change

WordPress Trac noreply at wordpress.org
Tue Jul 11 04:23:46 UTC 2017


#41271: Customizer sanitize_callback gets called multiple times on setting change
----------------------------+------------------------------
 Reporter:  kylejennings83  |       Owner:
     Type:  defect (bug)    |      Status:  new
 Priority:  normal          |   Milestone:  Awaiting Review
Component:  Customize       |     Version:  4.8
 Severity:  normal          |  Resolution:
 Keywords:                  |     Focuses:  performance
----------------------------+------------------------------
Changes (by westonruter):

 * focuses:   => performance


Comment:

 @kylejennings83 It's hard to say why the specific number is called without
 seeing your full codebase. If you look at
 `WP_Customize_Setting::preview()` you'll see that it does:

 {{{
 add_filter( "theme_mod_{$id_base}", array( $this, '_preview_filter' ) );
 }}}

 That means whenever you do `get_theme_mod( 'sidebar_size_setting' )` it is
 going to call the `WP_Customize_Setting::_preview_filter()` method, which
 in turn is going to grab the unsanitized value and pass it through the
 `sanitize_callback`. So each time you try to read from the setting the
 sanitize logic will be re-run.

 Here is a more robust way to log these sanitize calls:

 {{{#!php
 <?php
 $calls = array();

 add_action( 'wp_footer', function() use ( &$calls ) {
         error_log( print_r( $calls, true ) );
 } );

 add_filter( 'customize_sanitize_blogname', function( $value ) use (
 &$calls ) {
         global $wp_current_filter;
         $calls[] = array(
                 'hook_stack' => $wp_current_filter,
                 'call_stack' => array_slice( array_map(
                         function( $call ) {
                                 return sprintf( '%s() at %s:%d',
 $call['function'], preg_replace( '#.+/src/#', '', $call['file'] ),
 $call['line'] );
                         },
                         debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS )
                 ), 1 ),
         );
         return $value;
 } );
 }}}

 I've attached [attachment:blogname-setting-sanitize-calls.txt] to show the
 output. You can see the `get_option()` call is present in each call stack.

 To reduce the number of times the sanitization is done, we could add a
 caching layer to `\WP_Customize_Manager::post_value()`. So it could check
 to see if a setting had previously been validated or sanitized, and then
 short-circuit to return the previously computed values. The cached values
 can then be cleared whenever the `customize_post_value_set_{$setting_id}`
 action is fired.

 There hasn't been a clear demand for these changes in terms of any
 performance gains, but I'm happy to be shown otherwise.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/41271#comment:3>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list