-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Remove additional call to WP_Theme_JSON::_construct
#6271
Remove additional call to WP_Theme_JSON::_construct
#6271
Conversation
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN:
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
@joemcgill With the latest changes we are getting a consistent 2.5% improvement without breaking anything.
|
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.
Good find, @kt-12. This looks like a smart improvement to me. I believe the original implementation for these filters were done as part of WordPress/gutenberg#44015. @oandregal do you recall any reason why the WP_Theme_JSON_Data
objects needed to return the raw theme.json
data just to have them built back into new WP_Theme_JSON
objects?
Profiling this PR, I can see that this reduces calls of WP_Theme_JSON::_construct()
by 8, saving a measurable amount of time and memory.
Before
After
WP_Theme_JSON::__construct
WP_Theme_JSON::__construct
WP_Theme_JSON::_construct
fix grammar Co-authored-by: Pascal Birchler <pascal.birchler@gmail.com>
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 have a small feedback concerning the Dockblock proposed for get_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.
I really like this PR, it shows attention to detail and understanding the flows. Thank you, @kt-12!
I haven't checked the performance impact, as I've seen others have done that and even if there was none this would have been a nice clean up.
I've checked a few things:
- Origins are still setup properly.
- Nothing changes for consumers in ways that they can unintentionally mess it up and doesn't require them to do anything.
- The processes done for incoming data (sanitization, migrating to new theme.json version, etc.) are still in place — before were happening twice, actually.
Oh, by the way. It'd be nice if this change would have been done first in the Gutenberg codebase. The value that provides is immense to all of us, including easier synchronization and quick feedback from Gutenberg users if we've missed something. I have nothing against merging it in wordpress-develop first, though I'd kindly ask that the authors port the same PR to Gutenberg. Until we figure out something better, this is what we collectively have and need to care for. |
Thank you @oandregal for your feedback. We clearly understand your feedback about Gutenberg first approach, hence we have already created a PR for Gutenberg - WordPress/gutenberg#61262 . Once it's tested and approved on Gutenberg we can then plan to merge it for the core. |
@@ -543,8 +538,7 @@ public static function get_user_data() { | |||
|
|||
/** This filter is documented in wp-includes/class-wp-theme-json-resolver.php */ | |||
$theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); | |||
$config = $theme_json->get_data(); | |||
static::$user = new WP_Theme_JSON( $config, 'custom' ); | |||
static::$user = $theme_json->get_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.
One thing I've noticed after reviewing the Gutenberg PR WordPress/gutenberg#61262 is that this is different in Gutenberg: there, we do $config['isGlobalStylesUserThemeJSON'] = true;
before the call to WP_Theme_JSON
. We need to consolidate that logic.
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.
It looks like #6616 will undo 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.
@talldan w.r.t to keeping both the repos same, that change should be fine. But w.r.t performance we might need to find a better way to do that later on.
Thank you so much 🙏 I approved the Gutenberg PR. By reviewing the Gutenberg PR I noticed that the core code is missing a check: see #6271 (comment) and https://github.com/WordPress/gutenberg/pull/61262/files#r1589940214. I don't know why they have differed but that check is important and we should consolidate both codebases. |
@@ -255,8 +254,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() | |||
* @param WP_Theme_JSON_Data $theme_json Class to access and update the underlying data. | |||
*/ | |||
$theme_json = apply_filters( 'wp_theme_json_data_theme', new WP_Theme_JSON_Data( $theme_json_data, 'theme' ) ); | |||
$theme_json_data = $theme_json->get_data(); | |||
static::$theme = new WP_Theme_JSON( $theme_json_data ); | |||
static::$theme = $theme_json->get_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.
There are some linting issues in the committed code, incorrect spacing before the equals signs here.
The main reason I'm looking at this though is that a new feature was merged in Gutenberg - WordPress/gutenberg#57908. It was testing fine prior to the changes on these lines, but after the change there's an exception being thrown by this change (I bisected to find it).
To repro:
- Make sure you have the latest core trunk and gutenberg trunk code checked out and built, you have the plugin active and are using twentytwentyfour as your theme
- Add a file with the following content into
wp-content/themes/twentytwentyfour/styles/block-style-contrast.json
:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 2,
"title": "Variation A",
"blockTypes": [ "core/group", "core/columns", "core/media-text" ],
"styles": {
"color": {
"background": "var(--wp--preset--color--contrast)",
"text": "var(--wp--preset--color--base)"
}
}
}
- Load the site editor, and you should see an error:
Warning: Undefined array key "styleVariations" in /var/www/html/wp-includes/class-wp-theme-json.php on line 2465
Warning: Trying to access array offset on value of type null in /var/www/html/wp-includes/class-wp-theme-json.php on line 2465
If you then revert the change on this line(s), the error goes away.
I don't have much of an understanding why this causes an issue. It'd be great to understand why it's happening before taking any action. I'll continue looking into it, but any help appreciated, as this'll need to be fixed prior to the 6.6 beta.
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.
@kt-12 @joemcgill @oandregal I think I have an understanding of what's happening, but worth noting I'm not an expert with these theme json classes.
The gutenberg codebase hooks into the wp_theme_json_data_theme
filter, but can return a WP_Theme_JSON_Gutenberg
from the filter. Before your change, it didn't really matter as core would construct a WP_Theme_JSON
from that, but now I think the change can mean core holding on to a WP_Theme_JSON_Gutenberg
reference. This might be leading to some incompatibilities in the data structures. At some point the newer WP_Theme_JSON_Gutenberg
data is being processed by an older WP_Theme_JSON
class, and that's when the error happens. I'm not sure exactly how that happens, still investigating.
The core backport for the feature (#6662) does resolve the issue, as it updates WP_Theme_JSON
to be compatible.
But I think there are question marks over what happens when the gutenberg plugin tries to implement new features in the future that extend the 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.
Thanks @talldan. We had this reported to the related Trac ticket and have created this follow-up PR to address the issue. If you could test it and confirm that it fixes the issue, I can get it committed.
But I think there are question marks over what happens when the gutenberg plugin tries to implement new features in the future that extend the theme json.
I think this is a very good question. I've had some discussion with @tellthemachines and @oandregal about making the WP_Theme_JSON_
related classes read only in the WP-dev repo and sync them from the GB repo the way we sync other packages, which is one way to solve these incompatibilities, but we've not confirmed that approach. I need to open a new issue for us to consider those changes.
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 didn't have time to look at this today but will do next week. This smells to a bug we need to fix, for which we have time in the beta period. I'm available and happy to help uncover the issue and prepare a fix. Please, ping me in any related tickets/PR (subscribed to the PRs & trac tickets mentioned).
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 finally got some time to look at this today. Sharing what I know.
The flow:
Steps | Core | Gutenberg plugin |
---|---|---|
1. | WP_Theme_JSON triggers the wp_theme_json_data_theme filter. |
|
2. | gutenberg_resolve_style_variations_* runs as a filter callback |
|
3. | Gutenberg builds its own WP_Theme_JSON_Data_Gutenberg which uses to validate the data (update_with ) and then returns. |
|
4. | WP_Theme_JSON receives the validated data. |
At 4, core receives some data and it expects it to be validated by the consumer of the filter (this is, the consumer uses update_with
). While Gutenberg validates the data properly, it uses different metadata/schema than core does.
In the particular case that Dan raised, Gutenberg was able to get more style variations than core had:
Variations detected by Gutenberg | Variations detected by core |
---|---|
For block core/columns: variation-a | |
For block core/group: variation-a | |
For block core/media-text: variation-a | |
For block core/button: outline | For block core/button: outline |
For block core/image: rounded | For block core/image: rounded |
For block core/quote: plain | For block core/quote: plain |
At the point of processing the variations, core is unable to find the first three variations, hence the PHP Warning: Undefined array key "styleVariations" in /var/www/src/wp-includes/class-wp-theme-json.php on line 2445
raised here. Before this PR, core did an extra validation step, getting rid of the extraneous data before processing it, so that never happened.
There's a few layers to this issue, and it only happens because Gutenberg is re-triggering the same filters than core (wp_theme_json_data_theme
). The consumers of the filters run twice (one for core and the second time for the plugin). It's the first time that it fails because the metadata/schemas are different.
Unlike this other issue, this is very Gutenberg-specific because it is the result of modifying the metadata/schema of the theme.json. I don't have any more time today to look into solutions, but wanted to share what I know about as soon as possible. I'll do some more testing in the next days to assess the severity and what can we do.
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.
For a different issue, I ended up proposing a change to how "block style variations" defined by the theme are registered at #6756 By doing that, the error reported by Dan no longer happens.
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.
Thanks for looking into this @oandregal. It still seems like this is very similar to https://core.trac.wordpress.org/ticket/61112, but seems like the problem is that because core is not converting the WP_Theme_JSON_Data_Gutenberg
object back into a WP_Theme_JSON_Data
object, the incompatibilities are possible.
It seems wrong that Gutenberg would return an object from these filters that are not compatible with WP_Theme_JSON_Data
objects, but we may be able to simply update the fix proposed in #6626 to check for whether the returned object is a WP_Theme_JSON_Data
object, and reprocess if not, rather than just if it a get_theme_json
method exists on the class.
As a matter of process, I think following up on this whole issue should be done in as a part of https://core.trac.wordpress.org/ticket/61112 so this doesn't get lost, so I'm going to summarize this issue on that ticket and update the PR with the new approach I just proposed.
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.
Trac ticket: Trac 61112
Corresponding Guttenberg PR - WordPress/gutenberg#61262
This was found while analysing https://core.trac.wordpress.org/ticket/59600, but it relates mostly https://core.trac.wordpress.org/ticket/57789
In this PR we are trying to avoid second call to
new WP_Theme_JSON( $theme_json_data );
as the data can be obtained fromWP_Theme_JSON_data
class using just a line above by introducing a new public method. At the micro level call toWP_Theme_JSON
constructor is expensive.Interestingly, I can see this change also improved static calls. I wasn't expecting that as in my opinion static lines are only executed once, however, this has challenged my view about static calls and might be we need to be mindful of the performance even while using static.
The execution time of the
wp_get_theme_data_custom_templates
function on the home page of TT4 was evaluated. Each page had two calls to the function. The second call was static cached so it was significantly lower than the time for the first call.The performance improvement was as noted below:
Before PR
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
Mean of first call: 0.003366
Mean of static call: 0.000787
After PR
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
wp_get_theme_data_custom_templates
Mean of first call: 0.002900
Mean of static call: 0.000470
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.