From fef356b3758a841c9b255cde43e7c0d7eee4fc66 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 27 Jan 2023 22:14:12 +0000 Subject: [PATCH] Editor: Use a non-persistent object cache in `wp_get_global_settings()`. This changeset is part of a greater effort to enhance the caching strategy for `theme.json` based data. Similar to [55138] and [55148], the cache is currently ignored when `WP_DEBUG` is on to avoid interrupting the theme developer's workflow. This addition of a non-persistent cache results in a significant performance improvement for the overall load time of WordPress, with the Server-Timing load metric being ~8% faster and Time to First Byte being 25+% faster than before. Props oandregal, spacedmonkey, hellofromtonya, flixos90, azaozz, aristath. Fixes #57502. Built from https://develop.svn.wordpress.org/trunk@55155 git-svn-id: http://core.svn.wordpress.org/trunk@54688 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/global-styles-and-settings.php | 58 ++++++++++++++++++++-- wp-includes/version.php | 2 +- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/wp-includes/global-styles-and-settings.php b/wp-includes/global-styles-and-settings.php index a814b5fe3b..5836bf15fa 100644 --- a/wp-includes/global-styles-and-settings.php +++ b/wp-includes/global-styles-and-settings.php @@ -25,15 +25,65 @@ */ function wp_get_global_settings( $path = array(), $context = array() ) { if ( ! empty( $context['block_name'] ) ) { - $path = array_merge( array( 'blocks', $context['block_name'] ), $path ); + $new_path = array( 'blocks', $context['block_name'] ); + foreach ( $path as $subpath ) { + $new_path[] = $subpath; + } + $path = $new_path; } + /* + * This is the default value when no origin is provided or when it is 'all'. + * + * The $origin is used as part of the cache key. Changes here need to account + * for clearing the cache appropriately. + */ $origin = 'custom'; - if ( isset( $context['origin'] ) && 'base' === $context['origin'] ) { + if ( + ! wp_theme_has_theme_json() || + ( isset( $context['origin'] ) && 'base' === $context['origin'] ) + ) { $origin = 'theme'; } - $settings = WP_Theme_JSON_Resolver::get_merged_data( $origin )->get_settings(); + /* + * By using the 'theme_json' group, this data is marked to be non-persistent across requests. + * See `wp_cache_add_non_persistent_groups` in src/wp-includes/load.php and other places. + * + * The rationale for this is to make sure derived data from theme.json + * is always fresh from the potential modifications done via hooks + * that can use dynamic data (modify the stylesheet depending on some option, + * settings depending on user permissions, etc.). + * See some of the existing hooks to modify theme.json behaviour: + * https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/ + * + * A different alternative considered was to invalidate the cache upon certain + * events such as options add/update/delete, user meta, etc. + * It was judged not enough, hence this approach. + * See https://github.com/WordPress/gutenberg/pull/45372 + */ + $cache_group = 'theme_json'; + $cache_key = 'wp_get_global_settings_' . $origin; + + /* + * Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme + * developer's workflow. + * + * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core. + */ + $can_use_cached = ! WP_DEBUG; + + $settings = false; + if ( $can_use_cached ) { + $settings = wp_cache_get( $cache_key, $cache_group ); + } + + if ( false === $settings ) { + $settings = WP_Theme_JSON_Resolver::get_merged_data( $origin )->get_settings(); + if ( $can_use_cached ) { + wp_cache_set( $cache_key, $settings, $cache_group ); + } + } return _wp_array_get( $settings, $path, $settings ); } @@ -317,5 +367,7 @@ function wp_theme_has_theme_json() { */ function wp_clean_theme_json_cache() { wp_cache_delete( 'wp_get_global_stylesheet', 'theme_json' ); + wp_cache_delete( 'wp_get_global_settings_custom', 'theme_json' ); + wp_cache_delete( 'wp_get_global_settings_theme', 'theme_json' ); WP_Theme_JSON_Resolver::clean_cached_data(); } diff --git a/wp-includes/version.php b/wp-includes/version.php index 1566e8eae4..8c55c49350 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.2-alpha-55154'; +$wp_version = '6.2-alpha-55155'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.