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

Make theme.json object caches non persistent #46150

Merged
merged 9 commits into from
Nov 30, 2022

Conversation

oandregal
Copy link
Member

@oandregal oandregal commented Nov 29, 2022

Related #45372
Part of #45171

What?

This PR makes the object caches in use for theme.json related data non-persistent.

Why?

Upon some conversations at #45372 people find that there are a couple of cases for which the invalidation of cache may be not enough:

  • Consumers that hook into theme.json data using dynamic data (hooking or not based on an options or user meta value). The alternative would be to invalidate the cache upon certain events (plugin de/activation, option ad/update/delete, etc.).
  • Updates that are not done via the regular WordPress mechanism (FTP updates, updates managed via git repositories, etc.). The alternative is asking consumers to clear the cache manually if they use a persistent cache plugin.

To unblock that PR, this makes the data non-persistent.

How?

  • Adds theme_json to the list of cache groups not to persist.
  • Removes the existing filters that took care of invalidating the cache for across-request situations: plugin de/activation, global styles post update.

Testing Instructions

  • Go to the global styles sidebar in site editor, do some changes (e.g.: change background color) and save.
  • Go to the front-end and verify that the changes are reflected immediately.

@oandregal oandregal self-assigned this Nov 29, 2022
@oandregal oandregal added the Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json label Nov 29, 2022
@oandregal
Copy link
Member Author

oandregal commented Nov 29, 2022

Personally, I'd like to revisit this decision later, and try using a persistent approach plus flushing the cache upon certain site events (plugin de/activation, options add/update/remove, etc.). Given the great gains of #45372 I'd rather prioritize shipping it and look into this later.

function _gutenberg_add_non_persistent_theme_json_cache_group() {
wp_cache_add_non_persistent_groups( 'theme_json' );
}
add_action( 'init', '_gutenberg_add_non_persistent_theme_json_cache_group' );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what hook would be best to set this group to non-persistent. Any ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe plugins_loaded

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 At that point, any plugin that implement persistent cache should be loaded, hence calling this method should be effective. Sounds good.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oandregal oandregal force-pushed the update/make-theme-json-cache-non-persistent branch from bb0266f to 83af27a Compare November 29, 2022 11:55
* When backporting to core, the existing filters hooked to WP_Theme_JSON_Resolver::clean_cached_data()
* need to be removed.
*/
add_action( 'start_previewing_theme', '_gutenberg_clean_theme_json_caches' );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only left the start_previewing_theme and switch_theme events as they are necessary for certain flows (preview themes, theme directory) that may access the theme data before they are dispatched.

These new events were introduced in 14.7 (stylesheet PR) when we aimed to make this persistent and can be removed: activated_plugin, deactivated_plugin, upgrader_process_complete.

With this change, all caches need the same invalidation logic, so I've consolidated it into a single place as per feedback at #45372 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we merge #45955, it will mean that no cache invalidation will be needed for start_previewing_theme / switch_theme, as the act of changing / filter the stylesheet option, will cache the cache key.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It requires more changes than that: data cached by wp_theme_has_theme_json, gutenberg_get_global_styles, and WP_Theme_JSON_Resolver all needs to be cached by stylesheet. If/When we do that, we can remove these hooks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching themes, mean we do not have cache to clear, as each theme would have it's own cache.

Copy link
Member

@aristath aristath Nov 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching themes, mean we do not have cache to clear, as each theme would have it's own cache.

I agree. However... clearing the cache won't be a bad thing since we'll be saving some memory 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is that to be able to remove these hooks, we need we make changes to those three places. It cannot be done in this PR or #45955 that only addresses wp_theme_has_theme_json as far as I could see.

/**
* Clean the cache used by the `gutenberg_get_global_stylesheet` function.
*/
function gutenberg_get_global_stylesheet_clean_cache() {
Copy link
Member Author

@oandregal oandregal Nov 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was introduced at #45679 and is slated for the 14.7 release. I've marked this PR for that release as well, so we can remove it. If this does not make it to the 14.7 we should deprecate it instead.

) {
wp_theme_has_theme_json_clean_cache();
}
function wp_theme_has_theme_json_clean_cache() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was introduced in 14.5 at #45543 so I'd rather deprecate it to be safe.

@oandregal oandregal added this to the Gutenberg 14.7 milestone Nov 29, 2022
Copy link
Member

@spacedmonkey spacedmonkey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@oandregal oandregal merged commit 41b0e39 into trunk Nov 30, 2022
@oandregal oandregal deleted the update/make-theme-json-cache-non-persistent branch November 30, 2022 08:12
@oandregal oandregal added the [Type] Performance Related to performance efforts label Nov 30, 2022
@oandregal
Copy link
Member Author

The main bulk of this PR is being backported at WordPress/wordpress-develop#3712

mpkelly pushed a commit to mpkelly/gutenberg that referenced this pull request Dec 7, 2022
felixarntz added a commit that referenced this pull request Dec 26, 2022
pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Jan 18, 2023
Adds `wp_theme_has_theme_json()` for public consumption, to replace the private internal Core-only `WP_Theme_JSON_Resolver::theme_has_support()` method. This new global function checks if a theme or its parent has a `theme.json` file.

For performance, results are cached as an integer `1` or `0` in the `'theme_json'` group with `'wp_theme_has_theme_json'` key. This is a non-persistent cache. Why? To make the 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.).

Also adds a new public function `wp_clean_theme_json_cache()` to clear the cache on `'switch_theme'` and `start_previewing_theme'`.

References:
* [WordPress/gutenberg#45168 Gutenberg PR 45168] Add `wp_theme_has_theme_json` as a public API to know whether a theme has a `theme.json`.
* [WordPress/gutenberg#45380 Gutenberg PR 45380] Deprecate `WP_Theme_JSON_Resolver:theme_has_support()`.
* [WordPress/gutenberg#46150 Gutenberg PR 46150] Make `theme.json` object caches non-persistent.
* [WordPress/gutenberg#45979 Gutenberg PR 45979] Don't check if constants set by `wp_initial_constants()` are defined.
* [WordPress/gutenberg#45950 Gutenberg PR 45950] Cleaner logic in `wp_theme_has_theme_json`.

Follow-up to [54493], [53282], [52744], [52049], [50959].

Props oandregal, afragen, alexstine, aristath, azaozz, costdev, flixos90, hellofromTonya, mamaduka, mcsf, ocean90, spacedmonkey.
Fixes #56975.

git-svn-id: https://develop.svn.wordpress.org/trunk@55086 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Jan 18, 2023
Adds `wp_theme_has_theme_json()` for public consumption, to replace the private internal Core-only `WP_Theme_JSON_Resolver::theme_has_support()` method. This new global function checks if a theme or its parent has a `theme.json` file.

For performance, results are cached as an integer `1` or `0` in the `'theme_json'` group with `'wp_theme_has_theme_json'` key. This is a non-persistent cache. Why? To make the 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.).

Also adds a new public function `wp_clean_theme_json_cache()` to clear the cache on `'switch_theme'` and `start_previewing_theme'`.

References:
* [WordPress/gutenberg#45168 Gutenberg PR 45168] Add `wp_theme_has_theme_json` as a public API to know whether a theme has a `theme.json`.
* [WordPress/gutenberg#45380 Gutenberg PR 45380] Deprecate `WP_Theme_JSON_Resolver:theme_has_support()`.
* [WordPress/gutenberg#46150 Gutenberg PR 46150] Make `theme.json` object caches non-persistent.
* [WordPress/gutenberg#45979 Gutenberg PR 45979] Don't check if constants set by `wp_initial_constants()` are defined.
* [WordPress/gutenberg#45950 Gutenberg PR 45950] Cleaner logic in `wp_theme_has_theme_json`.

Follow-up to [54493], [53282], [52744], [52049], [50959].

Props oandregal, afragen, alexstine, aristath, azaozz, costdev, flixos90, hellofromTonya, mamaduka, mcsf, ocean90, spacedmonkey.
Fixes #56975.
Built from https://develop.svn.wordpress.org/trunk@55086


git-svn-id: http://core.svn.wordpress.org/trunk@54619 1a063a9b-81f0-0310-95a4-ce76da25c4cd
github-actions bot pushed a commit to gilzow/wordpress-performance that referenced this pull request Jan 18, 2023
Adds `wp_theme_has_theme_json()` for public consumption, to replace the private internal Core-only `WP_Theme_JSON_Resolver::theme_has_support()` method. This new global function checks if a theme or its parent has a `theme.json` file.

For performance, results are cached as an integer `1` or `0` in the `'theme_json'` group with `'wp_theme_has_theme_json'` key. This is a non-persistent cache. Why? To make the 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.).

Also adds a new public function `wp_clean_theme_json_cache()` to clear the cache on `'switch_theme'` and `start_previewing_theme'`.

References:
* [WordPress/gutenberg#45168 Gutenberg PR 45168] Add `wp_theme_has_theme_json` as a public API to know whether a theme has a `theme.json`.
* [WordPress/gutenberg#45380 Gutenberg PR 45380] Deprecate `WP_Theme_JSON_Resolver:theme_has_support()`.
* [WordPress/gutenberg#46150 Gutenberg PR 46150] Make `theme.json` object caches non-persistent.
* [WordPress/gutenberg#45979 Gutenberg PR 45979] Don't check if constants set by `wp_initial_constants()` are defined.
* [WordPress/gutenberg#45950 Gutenberg PR 45950] Cleaner logic in `wp_theme_has_theme_json`.

Follow-up to [54493], [53282], [52744], [52049], [50959].

Props oandregal, afragen, alexstine, aristath, azaozz, costdev, flixos90, hellofromTonya, mamaduka, mcsf, ocean90, spacedmonkey.
Fixes #56975.
Built from https://develop.svn.wordpress.org/trunk@55086


git-svn-id: https://core.svn.wordpress.org/trunk@54619 1a063a9b-81f0-0310-95a4-ce76da25c4cd
VenusPR added a commit to VenusPR/Wordpress_Richard that referenced this pull request Mar 9, 2023
Adds `wp_theme_has_theme_json()` for public consumption, to replace the private internal Core-only `WP_Theme_JSON_Resolver::theme_has_support()` method. This new global function checks if a theme or its parent has a `theme.json` file.

For performance, results are cached as an integer `1` or `0` in the `'theme_json'` group with `'wp_theme_has_theme_json'` key. This is a non-persistent cache. Why? To make the 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.).

Also adds a new public function `wp_clean_theme_json_cache()` to clear the cache on `'switch_theme'` and `start_previewing_theme'`.

References:
* [WordPress/gutenberg#45168 Gutenberg PR 45168] Add `wp_theme_has_theme_json` as a public API to know whether a theme has a `theme.json`.
* [WordPress/gutenberg#45380 Gutenberg PR 45380] Deprecate `WP_Theme_JSON_Resolver:theme_has_support()`.
* [WordPress/gutenberg#46150 Gutenberg PR 46150] Make `theme.json` object caches non-persistent.
* [WordPress/gutenberg#45979 Gutenberg PR 45979] Don't check if constants set by `wp_initial_constants()` are defined.
* [WordPress/gutenberg#45950 Gutenberg PR 45950] Cleaner logic in `wp_theme_has_theme_json`.

Follow-up to [54493], [53282], [52744], [52049], [50959].

Props oandregal, afragen, alexstine, aristath, azaozz, costdev, flixos90, hellofromTonya, mamaduka, mcsf, ocean90, spacedmonkey.
Fixes #56975.
Built from https://develop.svn.wordpress.org/trunk@55086


git-svn-id: http://core.svn.wordpress.org/trunk@54619 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Type] Performance Related to performance efforts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants