-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Fix wp_head
performance regression for classic themes
#3536
Conversation
…sic theme without support.
cc @oandregal |
👋 I've seen the changes and this is what I can share:
Coincidentally, for the area of "theme.json APIs", I'm compiling a list of tasks I find most pressing at WordPress/gutenberg#45171 I'm very optimistic about how those will impact the performance and code quality. For example, I've just published a prototype that reduces the total time of a request from 514.44ms to 343.71ms, a 33% performance increase. Another thing that it'd be useful is to prepare these PRs directly in Gutenberg. That way, they can be tested widely and bugs will be raised earlier than the WordPress RC cycles, which is always a lot less stressful and give people time to figure out long-term solutions rather than patches for the RC. |
Felix, would you share the steps you did to test this, so it can be replicated in a variety of environments? As a side note, it'd be great to track some statistics across WordPress versions and watch its evolution, like we do for the editor (see live at https://codehealth.vercel.app/). |
@oandregal Thank you for providing additional context on why (parts of) these methods are needed for classic themes as well. Based on what you're saying, I still think there are a number of performance optimizations to make here to avoid running FSE-only logic for classic themes. Here are some of the high-level ideas I'm thinking:
I'll make some updates to the proposed code here accordingly, the main thing though that requires some more work would be to generate some version of a
It was a fairly basic process, here's what I did:
If we wanted to dive in more deeply, it would also be interesting to see what the difference would be on a more complex piece of content, e.g. the Gutenberg demo page. |
… pre-built PHP-parsed version of WP core theme.json if present.
@oandregal I've pushed some updates here as mentioned above, please have a look. I have included what the One additional concern/question I have: Why is the condition around whether to reuse the previously "cached" theme data only present around parsing the (child) theme's |
This PR is heavily related - #3556. |
This is hard to code review the code to generate theme-php.php, fix the unit test and coding standards. |
No point to review the I'll work on further polishing here today. @draganescu @hellofromtonya Any chance I could get your thoughts on the changes and proposed approach from this draft PR? Please make sure to review my above issue comments for context. |
I don't think we should merge this without the automatic generation code, in JS grunt. I think we should consider making this out to another PR, where we have more time to review / test. |
That's exactly what I'm saying.
Sounds good, I've opened WordPress/gutenberg#45616 for that. Will remove the |
@spacedmonkey @draganescu @hellofromtonya This PR is now ready for a full review, including test coverage. Would be great to get your feedback so that we can aim to get this into 6.1.1. |
@@ -582,8 +593,8 @@ public static function get_user_global_styles_post_id() { | |||
public static function theme_has_support() { | |||
if ( ! isset( static::$theme_has_support ) ) { | |||
static::$theme_has_support = ( | |||
is_readable( static::get_file_path_from_theme( 'theme.json' ) ) || | |||
is_readable( static::get_file_path_from_theme( 'theme.json', true ) ) | |||
static::get_file_path_from_theme( 'theme.json' ) !== '' || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nice, get_file_path_from_theme
already calls is_readable
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a fwe notes inline.
static::get_file_path_from_theme( 'theme.json' ) !== '' || | ||
static::get_file_path_from_theme( 'theme.json', true ) !== '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yoda
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed here. Yoda conditions are only required around variable to value comparisons, not with functions (since setting a function to another value would result in an error anyway).
@@ -400,6 +408,9 @@ 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() ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only edge case I can think of is a theme that uses theme.json
and removes it in a later version. In that case, this changes the behavior: the code will now ignore user data while it was used before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
YES! Love this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a fair point. However, I would consider this indeed an edge-case which I don't think is worth addressing here. If a theme removed its theme.json
it would come with a whole lot of other behavioral changes anyway - I don't think realistically any theme author is going to change a block theme to become a classic theme.
👋 I've run some local profiling tests using TwentyTwentyOne. My test was loading the "hello world" post as a logged-out user. These are the numbers (median of 9 tries): it takes 393.98ms with this request and 411.04ms without these changes. This improves 17.06ms, a 4.15% improvement for that theme. |
For reference, block themes also improve in 12.47ms. This PR does a few changes: 1. remove I've done my testing with TwentyTwentyOne and TwentyTwentyThree (none is a child theme). Given the changes and the numbers are so close (-12ms vs -17ms for themes with and without I'm a bit torn about whether this is worth doing. It'd be great if we could see if only applying the changes at 1 and 2 brings the same amount of improvement. If that's the case I'd remove all the other changes, as they make the code harder to read and would not bring a gain worth pursuing. As I said, I won't have much time to look into this in the following days, though it looks like a safe change from a code point of view. Hope this is helpful. |
I also want to share the two things that I consider more impactful at the moment to focus on:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR works. It doesn't solve all the issues in wp_head, but it a great start
@oandregal Thank you for running additional performance benchmarks on the latest code here! This is super helpful. I've also run the latest iteration of the PR through the same methodology that I originally used, and posted results in an updated PR description. Of course the benefit is much less than originally, now that I've broken out fixing the core |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a nit pick inline
Co-authored-by: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
…lixarntz/wordpress-develop into fix/classic-themes-wp_head-regression
Committed in https://core.trac.wordpress.org/changeset/54799. |
wp_head
due to additional logic focused on FSE, which particularly for classic themes appears to be unnecessary.wp_head
execution time from 16.45ms to 11.92ms (~28% faster) for classic themes (concretely tested with Twenty Twenty-One), while apparently not missing any actual functionality needed.wp_head
performance regression for classic themes #3536 (comment), a more complex part of this implementation was broken out into a separate Gutenberg PR Create parsed PHP version of core'stheme.json
at build time rather than during runtime gutenberg#45616, so that the rest of this PR can realistically make it into the WordPress 6.1.1 release.wp_head
execution time from 16.45ms to 14.78ms (~10% faster) for the same test environment. This is quite a bit less of an improvement from the original, but it makes sense as with the latest implementation still core'stheme.json
andtheme-i18n.json
files are being parsed. That said, this still brings a worthwhile performance improvement and sets the stage for the follow up work in Create parsed PHP version of core'stheme.json
at build time rather than during runtime gutenberg#45616 to address the remaining part of the performance issues.cc @scruffian @oandregal @draganescu
Trac ticket: https://core.trac.wordpress.org/ticket/56945
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.