-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Font Collections: lazy load json configuration for better performance #58530
Conversation
This pull request has changed or added PHP files. Please confirm whether these changes need to be synced to WordPress Core, and therefore featured in the next release of WordPress. If so, it is recommended to create a new Trac ticket and submit a pull request to the WordPress Core Github repository soon after this pull request is merged. If you're unsure, you can always ask for help in the #core-editor channel in WordPress Slack. Thank you! ❤️ View changed files❔ phpunit/tests/fonts/font-library/wpFontCollection/getData.php ❔ lib/compat/wordpress-6.5/fonts/class-wp-font-collection.php ❔ lib/compat/wordpress-6.5/fonts/class-wp-font-library.php ❔ lib/compat/wordpress-6.5/fonts/class-wp-rest-font-collections-controller.php ❔ lib/compat/wordpress-6.5/fonts/class-wp-rest-font-faces-controller.php ❔ lib/compat/wordpress-6.5/fonts/class-wp-rest-font-families-controller.php ❔ lib/compat/wordpress-6.5/fonts/fonts.php ❔ phpunit/tests/fonts/font-library/wpFontCollection/__construct.php ❔ phpunit/tests/fonts/font-library/wpFontLibrary/registerFontCollection.php ❔ phpunit/tests/fonts/font-library/wpRestFontCollectionsController.php |
If I register a font collection like this wp_register_font_collection( 'https://dummyjson.com/products/1' ); I get 2 warnings. The second one seems unexpected. Notice: Function WP_Font_Collection::validate_config was called incorrectly. Font collection "https-dummyjson-com-products-1" does not contain any font families. Please see Debugging in WordPress for more information. (This message was added in version 6.5.0.) in /var/www/html/wp1/wp-includes/functions.php on line 6031
Notice: Function WP_Font_Collection::__construct was called incorrectly. Font collection slug "https://dummyjson.com/products/1" is not valid. Slugs must use only alphanumeric characters, dashes, and underscores. Please see Debugging in WordPress for more information. (This message was added in version 6.5.0.) in /var/www/html/wp1/wp-includes/functions.php on line 6031 And the collection is listed like this in the REST API: {
"slug": "https-dummyjson-com-products-1",
"name": "Unnamed Font Collection",
"description": ""
}, If I register the collection using a hook: function register_collections() {
wp_register_font_collection( 'https://dummyjson.com/products/1' );
}
add_action( 'rest_api_init', 'register_collections' ); I get no warning and the same API response: {
"slug": "https-dummyjson-com-products-1",
"name": "Unnamed Font Collection",
"description": ""
}, |
*/ | ||
function wp_register_font_collection_from_json( $file_or_url ) { | ||
return WP_Font_Library::register_font_collection_from_json( $file_or_url ); | ||
function wp_register_font_collection( $slug, $args_or_file = array() ) { |
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 seems like both arguments should be mandatory now because without $args_or_file
, the collection is useless, and the data can't be added after the construction of the object.
Currently, you can call the function like this:
wp_register_font_collection( 'https://dummyjson.com/products/1' );
without getting any notice about the lack of the correct number of parameters.
I think a _doing_it_wrong notice is needed for the function to be called with only one parameter.
Apart from that, the collection should not be registered as is happening in this example:
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.
wp_register_font_collection
and related functions have been updated to require both function parameters.
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 SVNIf you're a Core Committer, use this list when committing to
GitHub Merge commitsIf you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
877c9d4
to
fa2ea8c
Compare
This PR is now updated and should be ready for review. |
wp_register_font_collection_from_json( 'https://raw.githubusercontent.com/WordPress/google-fonts-to-wordpress-collection/01aa57731575bd13f9db8d86ab80a2d74e28a1ac/releases/gutenberg-17.6/collections/google-fonts-with-preview.json' ); | ||
function gutenberg_register_font_collections() { | ||
// TODO: update to production font collection URL. | ||
wp_register_font_collection( 'google-fonts', 'https://raw.githubusercontent.com/WordPress/google-fonts-to-wordpress-collection/01aa57731575bd13f9db8d86ab80a2d74e28a1ac/releases/gutenberg-17.6/collections/google-fonts-with-preview.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.
What's the story of this random URL? Can we replace it with a build script or something? I'm sure that including this as is into WordPress Core is a no go.
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 URL is provisional until the last version of the file is deployed WordPress.org CDN.
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.
random URL?
Do you refer to the domain of the URL or the fact that is loading from an external URL?
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.
If it's WordPress.org CDN, I'm ok with that, I believe we already use that CDN in a few places on WordPress already.
Should we just use the outdated version for now? I mean should we make the change in Gutenberg (and the Core patch)
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.
Some fields were added to the data of the file. Until the current file version is deployed to the CDN, we must use a file with all the required fields. As soon as we get the new file deployed to the CDN, we can replace that URL.
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.
@matiasbenedetto What's blocking the new file from being uploaded to the CDN?
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 latest changes will be merged soon and after that we will request to deploy the changes in this track ticket: https://meta.trac.wordpress.org/ticket/7282#ticket
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 deploy to the CDN was already requested here: https://meta.trac.wordpress.org/ticket/7282#comment:17
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 now, I've updated the url to the release version of the collection in Github.
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.
Reverted, I did that too soon, as the preview files aren't loaded at s.w.org yet.
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 see that the performance numbers are back to normal. Thanks for the fix. The code here is in general easier to follow for me as well.
I tested again the latest changes. examples: wp_register_font_collection( 'collection-with-empty-data' , array() );
wp_register_font_collection( 'collection-with-fake-url' , 'https://dummyjson.com/products/1' ); API response {
"code": "font_collection_missing_property",
"message": "Font collection \"collection-with-empty-data\" has missing or empty property: \"name.\"",
"data": {
"status": 500
}
} We should output the collections that are working fine to avoid the error. Otherwise, one failing collection breaks all the other collections. |
// translators: %s: File path or url to font collection json file. | ||
$message = sprintf( __( 'Font collection JSON file "%s" is invalid or does not exist.', 'gutenberg' ), $file_or_url ); | ||
// translators: %s: File path or url to font collection JSON file. | ||
$message = __( 'Font collection JSON file is invalid or does not exist.', 'gutenberg' ); |
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 error may be returned in an API response, so I removed the file path from the message to avoid leaking the server folder structure.
*/ | ||
private static $collection_json_cache = array(); |
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 static caching is removed in favor of storing the collection data in the class instance after it's been loaded and verified.
if ( empty( $data['slug'] ) ) { | ||
// translators: %s: Font collection JSON URL. | ||
$message = sprintf( __( 'Font collection JSON file "%s" requires a slug.', 'gutenberg' ), $file ); | ||
_doing_it_wrong( __METHOD__, $message, '6.5.0' ); | ||
return new WP_Error( 'font_collection_invalid_json', $message ); | ||
} | ||
|
||
static::$collection_json_cache[ $file ] = $data; | ||
|
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 slug is now a required arg for both php and json collection registration and validated by the constructor.
c184ea3
to
20c88f9
Compare
This has been rebased and updated to resolve the error pointed out by @matiasbenedetto, now ready for another review. |
} | ||
|
||
return array( | ||
'body' => json_encode( self::$mock_collection_data ), |
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.
does this need to be wp_json_encode
?
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 catch. Seems best to be consistent. Updated in 6f0b823.
Still using the Github url until s.w.org is updated.
This reverts commit 4cc23a5.
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 use of a hook to register the collection seems to be breaking the unregistered function. The sequence of actions is altered. .
If I try to unregister the google-fonts
collection from a plugin, I get a notice, and the collection is not unregistered. Now the regression added in #58363 is fixed, the hook doesn't need to be necessary, so I think it can be removed.
Example:
wp_unregister_font_collection ( 'google-fonts' );
The response of the /font-collections/
endpoint
<b>Notice</b>: Function WP_Font_Library: :unregister_font_collection was called incorrectly. Font collection "google-fonts" not found. Please see <a>Debugging in WordPress</a> for more information. (This message was added in version 6.5.0.) in <b>/var/www/html/wp1/wp-includes/functions.php</b> on line <b>6031</b><br />
[
{
"slug": "google-fonts",
"name": "Google Fonts",
"description": "Install from Google Fonts. Fonts are copied to and served from your site."
}
]
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 like to rely on hook names to do that because that forces the extenders to understand the hooks and their order, which can be confusing. But due to this pattern being followed by other similar core functions, I think it's ok and should replicate that for consistency.
LGTM
Let's merge 🚀
What?
WP_Font_Collection
to access font collection data using a::get_data
method rather than public properties so that we can lazy load collection json and avoid making http requests or file reads when not neededwp_register_font_collection_from_json
in favor of providing a config array or a file path when usingwp_register_font_collection
init
rather than the global scopeWhy?
#58363 caused a performance regression. Although it added caching, making the initial request for the font collection json on collection registration causes an unnecessary http request on every page load.
Testing Instructions