Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix wp_head performance regression for classic themes #3536

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/wp-includes/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,9 @@ public static function get_theme_data( $deprecated = array(), $options = array()
$parent_theme = new WP_Theme_JSON( $parent_theme_json_data );

/*
* Merge the child theme.json into the parent theme.json.
* The child theme takes precedence over the parent.
*/
* Merge the child theme.json into the parent theme.json.
* The child theme takes precedence over the parent.
*/
$parent_theme->merge( static::$theme );
static::$theme = $parent_theme;
}
Expand Down Expand Up @@ -408,12 +408,16 @@ private static function remove_json_comments( $array ) {
* @return array Custom Post Type for the user's origin config.
*/
public static function get_user_data_from_wp_global_styles( $theme, $create_post = false, $post_status_filter = array( 'publish' ) ) {
if ( ! static::theme_has_support() ) {
return array();
}
if ( ! $theme instanceof WP_Theme ) {
$theme = wp_get_theme();
}

// Bail early if the theme does not support a theme.json. Since WP_Theme_JSON_Resolver::theme_has_support()
// only supports the active theme, the extra condition for whether $theme is the active theme is present here.
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
if ( $theme->get_stylesheet() === get_stylesheet() && ! static::theme_has_support() ) {
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
return array();
}

$user_cpt = array();
$post_type_filter = 'wp_global_styles';
$stylesheet = $theme->get_stylesheet();
Expand Down
48 changes: 19 additions & 29 deletions tests/phpunit/tests/theme/wpThemeJsonResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ class Tests_Theme_wpThemeJsonResolver extends WP_UnitTestCase {
*/
private $orig_theme_dir;

/**
* Queries.
*
* @var array
*/
private $queries = array();

/**
* WP_Theme_JSON_Resolver::$blocks_cache property.
*
Expand Down Expand Up @@ -105,7 +98,7 @@ public function set_up() {
add_filter( 'theme_root', array( $this, 'filter_set_theme_root' ) );
add_filter( 'stylesheet_root', array( $this, 'filter_set_theme_root' ) );
add_filter( 'template_root', array( $this, 'filter_set_theme_root' ) );
$this->queries = array();

// Clear caches.
wp_clean_themes_cache();
unset( $GLOBALS['wp_themes'] );
Expand All @@ -129,13 +122,6 @@ public function filter_set_locale_to_polish() {
return 'pl_PL';
}

function filter_db_query( $query ) {
if ( preg_match( '#post_type = \'wp_global_styles\'#', $query ) ) {
$this->queries[] = $query;
}
return $query;
}

/**
* @ticket 52991
* @ticket 54336
Expand Down Expand Up @@ -639,29 +625,35 @@ function test_get_user_data_from_wp_global_styles_does_not_use_uncached_queries(
wp_set_current_user( self::$administrator_id );
$theme = wp_get_theme();
WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
add_filter( 'query', array( $this, 'filter_db_query' ) );
$query_count = count( $this->queries );
$global_styles_query_count = 0;
add_filter(
'query',
function( $query ) use ( &$global_styles_query_count ) {
if ( preg_match( '#post_type = \'wp_global_styles\'#', $query ) ) {
$global_styles_query_count++;
}
return $query;
}
);
for ( $i = 0; $i < 3; $i++ ) {
WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
WP_Theme_JSON_Resolver::clean_cached_data();
}
$query_count = count( $this->queries ) - $query_count;
$this->assertSame( 0, $query_count, 'Unexpected SQL queries detected for the wp_global_style post type prior to creation.' );
$this->assertSame( 0, $global_styles_query_count, 'Unexpected SQL queries detected for the wp_global_style post type prior to creation.' );

$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
$this->assertEmpty( $user_cpt, 'User CPT is expected to be empty.' );

$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme, true );
$this->assertNotEmpty( $user_cpt, 'User CPT is expected not to be empty.' );

$query_count = count( $this->queries );
$global_styles_query_count = 0;
for ( $i = 0; $i < 3; $i ++ ) {
$new_user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
WP_Theme_JSON_Resolver::clean_cached_data();
$this->assertSameSets( $user_cpt, $new_user_cpt, "User CPTs do not match on run {$i}." );
}
$query_count = count( $this->queries ) - $query_count;
$this->assertSame( 1, $query_count, 'Unexpected SQL queries detected for the wp_global_style post type after creation.' );
$this->assertSame( 1, $global_styles_query_count, 'Unexpected SQL queries detected for the wp_global_style post type after creation.' );
}

/**
Expand All @@ -672,13 +664,12 @@ function test_get_user_data_from_wp_global_styles_does_not_use_uncached_queries_
switch_theme( 'block-theme' );
$theme = wp_get_theme();
WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
add_filter( 'query', array( $this, 'filter_db_query' ) );
$query_count = count( $this->queries );
$query_count = get_num_queries();
for ( $i = 0; $i < 3; $i++ ) {
WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
WP_Theme_JSON_Resolver::clean_cached_data();
}
$query_count = count( $this->queries ) - $query_count;
$query_count = get_num_queries() - $query_count;
$this->assertSame( 0, $query_count, 'Unexpected SQL queries detected for the wp_global_style post type prior to creation.' );

$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
Expand All @@ -695,17 +686,16 @@ function test_get_user_data_from_wp_global_styles_does_not_run_for_theme_without
wp_set_current_user( self::$administrator_id );
$theme = wp_get_theme();

// Add filter to record DB query count.
add_filter( 'query', array( $this, 'filter_db_query' ) );
$start_queries = get_num_queries();

// When theme.json is not supported, the method should not run a query and always return an empty result.
$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
$this->assertEmpty( $user_cpt, 'User CPT is expected to be empty.' );
$this->assertSame( 0, count( $this->queries ), 'Unexpected SQL query detected for theme without theme.json support.' );
$this->assertSame( 0, get_num_queries() - $start_queries, 'Unexpected SQL query detected for theme without theme.json support.' );

$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme, true );
$this->assertEmpty( $user_cpt, 'User CPT is expected to be empty.' );
$this->assertSame( 0, count( $this->queries ), 'Unexpected SQL query detected for theme without theme.json support.' );
$this->assertSame( 0, get_num_queries() - $start_queries, 'Unexpected SQL query detected for theme without theme.json support.' );
}

/**
Expand Down