[wp-trac] [WordPress Trac] #63007: Bundled themes: Stylesheets for block themes are missing path data for inlining (was: Twenty Twenty-Five: Theme stylesheet is missing path data for inlining styles)

WordPress Trac noreply at wordpress.org
Mon Feb 24 23:07:28 UTC 2025


#63007: Bundled themes: Stylesheets for block themes are missing path data for
inlining
---------------------------+-------------------------------
 Reporter:  westonruter    |       Owner:  (none)
     Type:  defect (bug)   |      Status:  new
 Priority:  normal         |   Milestone:  6.8
Component:  Bundled Theme  |     Version:  6.7
 Severity:  normal         |  Resolution:
 Keywords:  has-patch      |     Focuses:  css, performance
---------------------------+-------------------------------

Old description:

> I'm investigating slow LCP caused by render delay due to external
> stylesheets. The Twenty Twenty-Five (TT5) theme enqueues its own small
> theme stylesheet with 7 style rules. However, it does so without adding
> the `path` style data which means this small stylesheet cannot be
> inlined. This negatively impacts LCP.
>

> Consider the following plugin code to test the performance impact of
> inlining the theme stylesheet as well as the stylesheet for the
> Navigation block which by default is not inlined since it is larger than
> the default inline style size limit of 20,000 bytes:
>
> {{{#!php
> <?php
> if ( isset( $_GET['styles_inline_size_limit'] ) ) {
>         add_filter( 'styles_inline_size_limit', function () {
>                 return intval( $_GET['styles_inline_size_limit'] );
>         } );
> }
>
> if ( isset( $_GET['inline_theme_stylesheet'] ) && rest_sanitize_boolean(
> $_GET['inline_theme_stylesheet'] ) ) {
>         add_action(
>                 'wp_enqueue_scripts',
>                 function () {
>                         wp_style_add_data(
>                                 'twentytwentyfive-style',
>                                 'path',
>                                 get_parent_theme_file_path( 'style.css' )
>                         );
>                 },
>                 20
>         );
> }
> }}}
>
> With this plugin in place and a vanilla site with TT5 active with the LCP
> element being text (`P`), I tested the following scenarios:
>
> 1. **Neither inlined:** The control behavior where the theme's stylesheet
> and the Navigation block's style sheet are not inlined.
> 2. **Theme inlined:** The theme's stylesheet is inlined but the
> Navigation block's stylesheet remains external.
> 3. **Navigation inlined:** The Navigation block's stylesheet is inlined
> but the theme's stylesheet remains external.
> 4. **Both inlined:** Both the theme's stylesheet and the Navigation
> block's stylesheet are inlined.
>
> These scenarios are accessed via the following URLs (`tt5-style-inlining-
> urls.txt`):
>
> {{{
> http://localhost:10063/?inline_theme_stylesheet=false
> http://localhost:10063/?inline_theme_stylesheet=true
> http://localhost:10063/?inline_theme_stylesheet=false&styles_inline_size_limit=40000
> http://localhost:10063/?inline_theme_stylesheet=true&styles_inline_size_limit=40000
> }}}
>

> I benchmarked via [https://github.com/GoogleChromeLabs/wpp-
> research/tree/main/cli#benchmark-web-vitals benchmark-web-vitals] with
> network emulating Slow 3G:
>
> {{{
> npm run research -- benchmark-web-vitals --file=tt5-style-inlining-
> urls.txt --number=25 --network-conditions="Slow 3G" --output=csv
> }}}
>
> Results:
>
> ||= Scenario =||= LCP-TTFB (median) =||
> || Neither inlined || 4196.1 ms||
> || Theme inlined || 4111.8 ms||
> || Navigation inlined || 4223.6 ms||
> || Both inlined ||  2230.8 ms||
>
> Inlining the theme styles reduces the LCP by 84.3 ms, which isn't a whole
> lot relatively at just ~2%. Inlining just the theme styles or the
> Navigation block styles alone doesn't significantly impact LCP, but if
> ''both'' are inlined then the LCP is cut in half, from a poor value to a
> good one.
>
> So I think that TT5 should add the `path` data for its stylesheet so it
> is eligible for inlining so that there could be the possibility for all
> render-blocking stylesheets to be avoided.
>
> Aside: When inlining a theme's `style.css` I think it would make sense to
> strip out the theme metadata comment automatically.

New description:

 I'm investigating slow LCP caused by render delay due to external
 stylesheets. The Twenty Twenty-Five (T25) and Twenty Twenty-Two (T22)
 themes enqueue their own small theme stylesheets (e.g. 7 style rules in
 TT5 and 13 in T22). However, it does so without adding the `path` style
 data which means this small stylesheet cannot be inlined. This negatively
 impacts LCP.


 Consider the following plugin code to test the performance impact of
 inlining the theme stylesheet as well as the stylesheet for the Navigation
 block which by default is not inlined since it is larger than the default
 inline style size limit of 20,000 bytes:

 {{{#!php
 <?php
 if ( isset( $_GET['styles_inline_size_limit'] ) ) {
         add_filter( 'styles_inline_size_limit', function () {
                 return intval( $_GET['styles_inline_size_limit'] );
         } );
 }

 if ( isset( $_GET['inline_theme_stylesheet'] ) && rest_sanitize_boolean(
 $_GET['inline_theme_stylesheet'] ) ) {
         add_action(
                 'wp_enqueue_scripts',
                 function () {
                         wp_style_add_data(
                                 'twentytwentyfive-style',
                                 'path',
                                 get_parent_theme_file_path( 'style.css' )
                         );
                 },
                 20
         );
 }
 }}}

 With this plugin in place and a vanilla site with TT5 active with the LCP
 element being text (`P`), I tested the following scenarios:

 1. **Neither inlined:** The control behavior where the theme's stylesheet
 and the Navigation block's style sheet are not inlined.
 2. **Theme inlined:** The theme's stylesheet is inlined but the Navigation
 block's stylesheet remains external.
 3. **Navigation inlined:** The Navigation block's stylesheet is inlined
 but the theme's stylesheet remains external.
 4. **Both inlined:** Both the theme's stylesheet and the Navigation
 block's stylesheet are inlined.

 These scenarios are accessed via the following URLs (`tt5-style-inlining-
 urls.txt`):

 {{{
 http://localhost:10063/?inline_theme_stylesheet=false
 http://localhost:10063/?inline_theme_stylesheet=true
 http://localhost:10063/?inline_theme_stylesheet=false&styles_inline_size_limit=40000
 http://localhost:10063/?inline_theme_stylesheet=true&styles_inline_size_limit=40000
 }}}


 I benchmarked via [https://github.com/GoogleChromeLabs/wpp-
 research/tree/main/cli#benchmark-web-vitals benchmark-web-vitals] with
 network emulating Slow 3G:

 {{{
 npm run research -- benchmark-web-vitals --file=tt5-style-inlining-
 urls.txt --number=25 --network-conditions="Slow 3G" --output=csv
 }}}

 Results:

 ||= Scenario =||= LCP-TTFB (median) =||
 || Neither inlined || 4196.1 ms||
 || Theme inlined || 4111.8 ms||
 || Navigation inlined || 4223.6 ms||
 || Both inlined ||  2230.8 ms||

 Inlining the theme styles reduces the LCP by 84.3 ms, which isn't a whole
 lot relatively at just ~2%. Inlining just the theme styles or the
 Navigation block styles alone doesn't significantly impact LCP, but if
 ''both'' are inlined then the LCP is cut in half, from a poor value to a
 good one.

 So I think that T25 and T22 should add the `path` data for its stylesheet
 so it is eligible for inlining so that there could be the possibility for
 all render-blocking stylesheets to be avoided.

 Aside: When inlining a theme's `style.css` I think it would make sense to
 strip out the theme metadata comment automatically.

--

Comment (by westonruter):

 Replying to [comment:6 sabernhardt]:
 > > There is a similar ticket in #58519.
 >
 > No, a proposal to inline and minify Twenty Twenty-Two's stylesheet would
 be very similar to this ticket.

 Oh! I missed that one. I'll update this ticket to actually include T22 in
 the scope. So this ticket would be about allowing inlining block themes'
 styles.

 > The `blocks.css` and dark color stylesheets are significantly larger,
 and I would not want those inline without minification.

 Nevertheless, the `blocks.css` stylesheets you
 [https://core.trac.wordpress.org/ticket/58519#comment:2 listed] are all
 less than 20K bytes, the `styles_inline_size_limit`. So they would be
 eligible for inlining. The largest `blocks.css` is from Twenty Thirteen at
 16,254 bytes. And we minify stylesheets in core themes (cf.
 [https://core.trac.wordpress.org/ticket/49665#comment:4 comment] from
 #49665), then this stylesheet is reduced to 11,299 bytes.

 > I also requested a performance metrics comparison for loading a
 //second// page (in addition the first) because browsers would already
 have the external file cached.

 We should do this, but note that the impact to an increase to the size of
 the HTML in the second page load will be lessened by Speculative Loading
 (#62503).

 > #58519 was closed simply because fixing bugs was/is a higher priority,
 especially for the older themes.

 Nevertheless, I think a better approach for inlining classic themes'
 `blocks.css` would be to split up the stylesheet into multiple
 stylesheets, one for each block. Then if we can enable
 `should_load_separate_core_block_assets` for classic themes, then we can
 only enqueue the specific theme block styles which are actually used via
 `wp_enqueue_block_style()`. This would require the use of output buffering
 from #43258 (which I've just milestoned for 6.8), however, since we'd need
 to inject the CSS from the `head` after the rest of the template has been
 rendered. Maybe the themes' blocks stylesheets can't be split up so
 easily, however.

 Replying to [comment:7 sabernhardt]:
 > I made a simple child theme to verify that the theme enqueues the
 (minified) parent stylesheet, and the current PR 8396 correctly loaded the
 TT5 styles inline for me with and without `SCRIPT_DEBUG` (but you could
 test again in case I missed something).

 Excellent. Yes, this is as expected since the
 `get_parent_theme_file_uri()` and `get_parent_theme_file_path()` functions
 are being used, not `get_stylesheet_uri()`. And the T22 theme is using
 `get_template_directory_uri() . '/style.css'` which is the same as doing
 `get_parent_theme_file_uri( 'style.css' )` with the added benefit of also
 applying the `parent_theme_file_uri` filter in addition to the
 `template_directory_uri` filter.

 So you approve the PR for commit?

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/63007#comment:8>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list