mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-04-02 11:44:33 +00:00
Customizer: Fix scalability performance problem for previewing multidimensional settings.
As the number of multidimensional settings (serialized options and theme mods) increase for a given ID base (e.g. a widget of a certain type), the number of calls to the `multidimensional` methods on `WP_Customize_Setting` increase exponentially, and the time for the preview to refresh grows in time exponentially as well. To improve performance, this change reduces the number of filters needed to preview the settings off of a multidimensional root from N to 1. This improves performance from `O(n^2)` to `O(n)`, but the linear increase is so low that the performance is essentially `O(1)` in comparison. This is achieved by introducing the concept of an "aggregated multidimensional" setting, where the root value of the multidimensional serialized setting value gets cached in a static array variable shared across all settings. Also improves performance by only adding preview filters if there is actually a need to do so: there is no need to add a filter if there is an initial value and if there is no posted value for a given setting (if it is not dirty). Fixes #32103. git-svn-id: https://develop.svn.wordpress.org/trunk@35007 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -102,7 +102,7 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase {
|
||||
$setting = new WP_Customize_Setting( $this->manager, $name, compact( 'type', 'default' ) );
|
||||
$this->assertEquals( $this->undefined, call_user_func( $type_options['getter'], $name, $this->undefined ) );
|
||||
$this->assertEquals( $default, $setting->value() );
|
||||
$setting->preview();
|
||||
$this->assertTrue( $setting->preview(), 'Preview should not no-op since setting has no existing value.' );
|
||||
$this->assertEquals( $default, call_user_func( $type_options['getter'], $name, $this->undefined ), sprintf( 'Expected %s(%s) to return setting default: %s.', $type_options['getter'], $name, $default ) );
|
||||
$this->assertEquals( $default, $setting->value() );
|
||||
|
||||
@@ -114,18 +114,18 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase {
|
||||
$setting = new WP_Customize_Setting( $this->manager, $name, compact( 'type', 'default' ) );
|
||||
$this->assertEquals( $initial_value, call_user_func( $type_options['getter'], $name ) );
|
||||
$this->assertEquals( $initial_value, $setting->value() );
|
||||
$setting->preview();
|
||||
$this->assertFalse( $setting->preview(), 'Preview should no-op since setting value was extant and no post value was present.' );
|
||||
$this->assertEquals( 0, did_action( "customize_preview_{$setting->id}" ) ); // only applicable for custom types (not options or theme_mods)
|
||||
$this->assertEquals( 0, did_action( "customize_preview_{$setting->type}" ) ); // only applicable for custom types (not options or theme_mods)
|
||||
$this->assertEquals( $initial_value, call_user_func( $type_options['getter'], $name ) );
|
||||
$this->assertEquals( $initial_value, $setting->value() );
|
||||
|
||||
// @todo What if we call the setter after preview() is called? If no post_value, should the new set value be stored? If that happens, then the following 3 assertions should be inverted
|
||||
$overridden_value = "overridden_value_$name";
|
||||
call_user_func( $type_options['setter'], $name, $overridden_value );
|
||||
$this->assertEquals( $initial_value, call_user_func( $type_options['getter'], $name ) );
|
||||
$this->assertEquals( $initial_value, $setting->value() );
|
||||
$this->assertNotEquals( $overridden_value, $setting->value() );
|
||||
$message = 'Initial value should be overridden because initial preview() was no-op due to setting having existing value and/or post value was absent.';
|
||||
$this->assertEquals( $overridden_value, call_user_func( $type_options['getter'], $name ), $message );
|
||||
$this->assertEquals( $overridden_value, $setting->value(), $message );
|
||||
$this->assertNotEquals( $initial_value, $setting->value(), $message );
|
||||
|
||||
// Non-multidimensional: Test unset setting being overridden by a post value
|
||||
$name = "unset_{$type}_overridden";
|
||||
@@ -133,7 +133,7 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase {
|
||||
$setting = new WP_Customize_Setting( $this->manager, $name, compact( 'type', 'default' ) );
|
||||
$this->assertEquals( $this->undefined, call_user_func( $type_options['getter'], $name, $this->undefined ) );
|
||||
$this->assertEquals( $default, $setting->value() );
|
||||
$setting->preview(); // activate post_data
|
||||
$this->assertTrue( $setting->preview(), 'Preview applies because setting has post_data_overrides.' ); // activate post_data
|
||||
$this->assertEquals( $this->post_data_overrides[ $name ], call_user_func( $type_options['getter'], $name, $this->undefined ) );
|
||||
$this->assertEquals( $this->post_data_overrides[ $name ], $setting->value() );
|
||||
|
||||
@@ -145,7 +145,7 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase {
|
||||
$setting = new WP_Customize_Setting( $this->manager, $name, compact( 'type', 'default' ) );
|
||||
$this->assertEquals( $initial_value, call_user_func( $type_options['getter'], $name, $this->undefined ) );
|
||||
$this->assertEquals( $initial_value, $setting->value() );
|
||||
$setting->preview(); // activate post_data
|
||||
$this->assertTrue( $setting->preview(), 'Preview applies because setting has post_data_overrides.' ); // activate post_data
|
||||
$this->assertEquals( 0, did_action( "customize_preview_{$setting->id}" ) ); // only applicable for custom types (not options or theme_mods)
|
||||
$this->assertEquals( 0, did_action( "customize_preview_{$setting->type}" ) ); // only applicable for custom types (not options or theme_mods)
|
||||
$this->assertEquals( $this->post_data_overrides[ $name ], call_user_func( $type_options['getter'], $name, $this->undefined ) );
|
||||
@@ -167,7 +167,7 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase {
|
||||
$setting = new WP_Customize_Setting( $this->manager, $name, compact( 'type', 'default' ) );
|
||||
$this->assertEquals( $this->undefined, call_user_func( $type_options['getter'], $base_name, $this->undefined ) );
|
||||
$this->assertEquals( $default, $setting->value() );
|
||||
$setting->preview();
|
||||
$this->assertTrue( $setting->preview() );
|
||||
$base_value = call_user_func( $type_options['getter'], $base_name, $this->undefined );
|
||||
$this->assertArrayHasKey( 'foo', $base_value );
|
||||
$this->assertEquals( $default, $base_value['foo'] );
|
||||
@@ -311,8 +311,8 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase {
|
||||
$this->assertEquals( $initial_value, $this->custom_type_getter( $name, $this->undefined ) );
|
||||
$this->assertEquals( $initial_value, $setting->value() );
|
||||
$setting->preview();
|
||||
$this->assertEquals( 1, did_action( "customize_preview_{$setting->id}" ) );
|
||||
$this->assertEquals( 2, did_action( "customize_preview_{$setting->type}" ) );
|
||||
$this->assertEquals( 0, did_action( "customize_preview_{$setting->id}" ), 'Zero preview actions because initial value is set with no incoming post value, so there is no preview to apply.' );
|
||||
$this->assertEquals( 1, did_action( "customize_preview_{$setting->type}" ) );
|
||||
$this->assertEquals( $initial_value, $this->custom_type_getter( $name, $this->undefined ) ); // should be same as above
|
||||
$this->assertEquals( $initial_value, $setting->value() ); // should be same as above
|
||||
|
||||
@@ -325,8 +325,8 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase {
|
||||
$this->assertEquals( $this->undefined, $this->custom_type_getter( $name, $this->undefined ) );
|
||||
$this->assertEquals( $default, $setting->value() );
|
||||
$setting->preview();
|
||||
$this->assertEquals( 1, did_action( "customize_preview_{$setting->id}" ) );
|
||||
$this->assertEquals( 3, did_action( "customize_preview_{$setting->type}" ) );
|
||||
$this->assertEquals( 1, did_action( "customize_preview_{$setting->id}" ), 'One preview action now because initial value was not set and/or there is no incoming post value, so there is is a preview to apply.' );
|
||||
$this->assertEquals( 2, did_action( "customize_preview_{$setting->type}" ) );
|
||||
$this->assertEquals( $post_data_overrides[ $name ], $this->custom_type_getter( $name, $this->undefined ) );
|
||||
$this->assertEquals( $post_data_overrides[ $name ], $setting->value() );
|
||||
|
||||
@@ -342,7 +342,7 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase {
|
||||
$this->assertEquals( $initial_value, $setting->value() );
|
||||
$setting->preview();
|
||||
$this->assertEquals( 1, did_action( "customize_preview_{$setting->id}" ) );
|
||||
$this->assertEquals( 4, did_action( "customize_preview_{$setting->type}" ) );
|
||||
$this->assertEquals( 3, did_action( "customize_preview_{$setting->type}" ) );
|
||||
$this->assertEquals( $post_data_overrides[ $name ], $this->custom_type_getter( $name, $this->undefined ) );
|
||||
$this->assertEquals( $post_data_overrides[ $name ], $setting->value() );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user