Opened 6 weeks ago
Closed 6 weeks ago
#64846 closed defect (bug) (fixed)
Loading separate styles on demand thwarted by plugins that register styles at 'init' with priority less than 8
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.0 | Priority: | normal |
| Severity: | normal | Version: | 6.9 |
| Component: | Script Loader | Keywords: | has-patch has-unit-tests needs-testing |
| Focuses: | css, performance | Cc: |
Description (last modified by )
This is a follow-up to #64099.
With Elementor patched to re-enable loading block styles on demand, I was confused to find that the single block library stylesheet was being loaded in spite of the output buffer being started and other styles being hoisted as expected. With Elementor deactivated, I would see on the frontend as expected the non-combined block-library common.css loaded:
<style id="wp-block-library-inline-css"> ... /*# sourceURL=/wp-includes/css/dist/block-library/common.css */ </style>
But with Elementor active, I see:
<link rel='stylesheet' id='wp-block-library-css' href='http://localhost:8000/wp-includes/css/dist/block-library/style.css?ver=7.0-beta4-61919-src' media='all' />
What's more is that I see the separate block styles also enqueued on top of the combined wp-block-library stylesheet:
<link rel='stylesheet' id='wp-block-library-css' href='http://localhost:8000/wp-includes/css/dist/block-library/style.css?ver=7.0-beta4-61919-src' media='all' />
<style id="wp-block-archives-inline-css">
.wp-block-archives {
box-sizing: border-box;
}
.wp-block-archives-dropdown label {
display: block;
}
/*# sourceURL=http://localhost:8000/wp-includes/blocks/archives/style.css */
</style>
The issue is that the elementor plugin initializes at the init action with priority 0 (source) which causes the default styles to be registered earlier than normal. The Elementor\Core\Page_Assets\Loader component which does wp_register_style():
#0 /var/www/src/wp-includes/script-loader.php(1829): WP_Dependencies->add() #1 /var/www/src/wp-includes/class-wp-hook.php(347): wp_default_styles() #2 /var/www/src/wp-includes/class-wp-hook.php(371): WP_Hook->apply_filters() #3 /var/www/src/wp-includes/plugin.php(570): WP_Hook->do_action() #4 /var/www/src/wp-includes/class-wp-styles.php(121): do_action_ref_array() #5 /var/www/src/wp-includes/functions.wp-styles.php(24): WP_Styles->__construct() #6 /var/www/src/wp-includes/functions.wp-styles.php(132): wp_styles() #7 /var/www/src/wp-content/plugins/elementor/core/page-assets/loader.php(172): wp_register_style() #8 /var/www/src/wp-content/plugins/elementor/core/page-assets/loader.php(181): Elementor\Core\Page_Assets\Loader->register_assets() #9 /var/www/src/wp-content/plugins/elementor/includes/plugin.php(711): Elementor\Core\Page_Assets\Loader->__construct() #10 /var/www/src/wp-content/plugins/elementor/includes/plugin.php(622): Elementor\Plugin->init_components() #11 /var/www/src/wp-includes/class-wp-hook.php(347): Elementor\Plugin->init() #12 /var/www/src/wp-includes/class-wp-hook.php(371): WP_Hook->apply_filters() #13 /var/www/src/wp-includes/plugin.php(522): WP_Hook->do_action()
At this point, when wp_default_styles() is called, this logic is run to register the wp-block-library style:
<?php $path = "/wp-includes/css/dist/$package/style$suffix.css"; if ( 'block-library' === $package && wp_should_load_separate_core_block_assets() ) { $path = "/wp-includes/css/dist/$package/common$suffix.css"; }
The issue is that wp_should_load_separate_core_block_assets() here returns false because wp_load_classic_theme_block_styles_on_demand() has run yet, since it runs later in the init action at priority 8:
add_action( 'init', 'wp_load_classic_theme_block_styles_on_demand', 8 ); // Must happen before register_core_block_style_handles() at priority 9.
This function is responsible for adding the adding the filters to opt-in to loading separate block styles on demand:
add_filter( 'should_load_separate_core_block_assets', '__return_true', 0 ); add_filter( 'should_load_block_assets_on_demand', '__return_true', 0 );
If the init priority of wp_load_classic_theme_block_styles_on_demand() is changed to -1 then this fixes the problem, but this is not the ideal solution since a theme/plugin could always register a style earlier during the init action (e.g. PHP_INT_MIN). Note that the init action is the earliest point to register a style safely since _wp_scripts_maybe_doing_it_wrong() will issue a warning otherwise. Nevertheless, the better solution would be to not use the init action at all, but rather to use the wp_default_styles action (with a low priority) so that we'll be better guaranteed that the filters will have been added.
Note: There are no relevant occurrences of wp_load_classic_theme_block_styles_on_demand() in indexed plugins or themes:
- Plugins: https://veloria.dev/search/1be0326b-db2f-4c25-af42-fa3dd8732221
- Themes: https://veloria.dev/search/f864055c-585c-4510-9045-4f02639d5906
So there is not a concern for back-compat for unhooking the function at init.
Reproduction
Activate this plugin:
<?php <?php /** * Plugin Name: Register test style at early init. * Plugin URI: https://core.trac.wordpress.org/ticket/64846 */ add_action( 'init', function () { wp_register_style( 'test-early-init', false ); wp_add_inline_style( 'test-early-init', '/* With a classic theme active, make sure wp-block-library is common.css and not style.css */' ); wp_enqueue_style( 'test-early-init' ); }, 0 );
This will reproduce the aforementioned issue observed with Elementor.
Change History (6)
This ticket was mentioned in PR #11232 on WordPress/wordpress-develop by @westonruter.
6 weeks ago
#4
- Keywords has-patch has-unit-tests added
Trac ticket: https://core.trac.wordpress.org/ticket/64846
The
wp_load_classic_theme_block_styles_on_demand()function was added to run atinitaction with priority 8 in r61008. This turns out to be too late since styles can be registered earlier. Registering a style earlier causeswp_default_styles()to be called, which registers thewp-block-librarystyle. When a classic theme is active, beforewp_load_classic_theme_block_styles_on_demand()is run, thewp_should_load_block_assets_on_demand()function will returnfalse. This results in the combined block library stylesheet being incorrectly registered:https://github.com/WordPress/wordpress-develop/blob/2bb252ae83bc78852c0d2e11749d640ac8b6bc8a/src/wp-includes/script-loader.php#L1819-L1823
The point of
wp_load_classic_theme_block_styles_on_demand()is to opt-in to loading separate block styles on demand, but at the point it runs it is already too late since the combinedwp-block-libraryhas already been registered.If the
initpriority ofwp_load_classic_theme_block_styles_on_demand()is changed to-1then this fixes the problem, but this is not the ideal solution since a theme/plugin could always register a style earlier during theinitaction (e.g.PHP_INT_MIN). Note that theinitaction is the earliest point to register a style safely since_wp_scripts_maybe_doing_it_wrong()will issue a warning otherwise. Nevertheless, the better solution would be to not use theinitaction at all, but rather to use thewp_default_stylesaction (with a low priority) so that we'll be better guaranteed that the filters will have been added.The issue can be reproduced with the following example plugin:
### Before ❌
### After ✅
## Use of AI Tools
None 🧠