[wp-trac] [WordPress Trac] #64846: Loading separate styles on demand thwarted by plugins that register styles at 'init' with priority less than 8
WordPress Trac
noreply at wordpress.org
Thu Mar 12 00:37:40 UTC 2026
#64846: Loading separate styles on demand thwarted by plugins that register styles
at 'init' with priority less than 8
---------------------------+-------------------------------
Reporter: westonruter | Owner: westonruter
Type: defect (bug) | Status: assigned
Priority: normal | Milestone: 7.0
Component: Script Loader | Version: 6.9
Severity: normal | Resolution:
Keywords: | Focuses: css, performance
---------------------------+-------------------------------
Description changed by westonruter:
Old description:
> This is a follow-up to #64099.
>
> With Elementor [https://github.com/elementor/elementor/pull/35084
> 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' />
> }}}
>
> The issue is that the elementor plugin initializes at the `init` action
> with priority 0
> ([https://github.com/elementor/elementor/blob/2a6322e09517d6149523a1b1aac8df9be144669a/includes/plugin.php#L825
> 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,
> [https://github.com/WordPress/wordpress-
> develop/blob/2bb252ae83bc78852c0d2e11749d640ac8b6bc8a/src/wp-includes
> /script-loader.php#L1819-L1823 this logic] is run to register the `wp-
> block-library` style:
>
> {{{#!php
> <?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
> [https://github.com/WordPress/wordpress-
> develop/blob/2bb252ae83bc78852c0d2e11749d640ac8b6bc8a/src/wp-includes
> /default-filters.php#L610 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.
>
> == Reproduction ==
>
> Activate this plugin:
>
> {{{#!php
> <?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.
New description:
This is a follow-up to #64099.
With Elementor [https://github.com/elementor/elementor/pull/35084 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
([https://github.com/elementor/elementor/blob/2a6322e09517d6149523a1b1aac8df9be144669a/includes/plugin.php#L825
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,
[https://github.com/WordPress/wordpress-
develop/blob/2bb252ae83bc78852c0d2e11749d640ac8b6bc8a/src/wp-includes
/script-loader.php#L1819-L1823 this logic] is run to register the `wp-
block-library` style:
{{{#!php
<?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
[https://github.com/WordPress/wordpress-
develop/blob/2bb252ae83bc78852c0d2e11749d640ac8b6bc8a/src/wp-includes
/default-filters.php#L610 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.
== Reproduction ==
Activate this plugin:
{{{#!php
<?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.
--
--
Ticket URL: <https://core.trac.wordpress.org/ticket/64846#comment:3>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list