Opened 19 months ago
Closed 18 months ago
#58394 closed enhancement (fixed)
Performance of wp_maybe_inline_styles
Reported by: | spacedmonkey | Owned by: | spacedmonkey |
---|---|---|---|
Milestone: | 6.3 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Script Loader | Keywords: | has-patch has-unit-tests |
Focuses: | performance | Cc: |
Description
The function wp_maybe_inline_styles
is called twice on templates. Hooked into wp_head
and wp_footer
. wp_maybe_inline_styles
loops through all register styles to inlines them. But a the file operations, like filesize
or file_get_contents
can be expensive. On the first run, there should be some level or caching or flag set, to ensure that this function can be run multiple times without run the expensive file operations more than once.
Change History (20)
This ticket was mentioned in PR #4500 on WordPress/wordpress-develop by @spacedmonkey.
19 months ago
#1
- Keywords has-patch added
#2
@
19 months ago
Brenchmark 1000 runs on TT3
Trunk | PR | |
Response Time (median) | 107.41 | 97.72 |
wp-load-alloptions-query (median) | 0.87 | 0.86 |
wp-before-template (median) | 51.6 | 50.04 |
wp-before-template-db-queries (median) | 4.35 | 4.25 |
wp-template (median) | 49.58 | 41.54 |
wp-total (median) | 101.94 | 92.05 |
wp-template-db-queries (median) | 2.51 | 2.44 |
#3
@
19 months ago
- Milestone changed from Future Release to 6.3
- Owner set to spacedmonkey
- Status changed from new to assigned
- Version 5.8 deleted
This is an excellent find!
I just conducted a benchmark for both TT3 (block theme) and TT1 (classic theme), and can report that there is definitely a notable impact on performance for both of them, even classic themes:
- For TT3,
wp-template
is ~21% faster, making overall response time ~7% faster. - For TT1,
wp-template
is ~5% faster, making overall response time ~2% faster.
That all makes sense, given that classic themes don't rely on the affected logic as heavily, e.g. don't commonly have stylesheets without a $src
enqueued. Still, even there the changes of caching the file size brings a performance benefit that is clear to see in the data.
Given this is a major performance win, I'll milestone this for 6.3.
@spacedmonkey commented on PR #4500:
19 months ago
#4
@joemcgill @felixarntz I am going to add some unit tests to wp_maybe_inline_styles
. Add it seems to have none at all :(
@spacedmonkey commented on PR #4500:
18 months ago
#5
@joemcgill @felixarntz Actioned feedback on tests. If you are happy, then I will commit.
@peterwilsoncc commented on PR #4500:
18 months ago
#6
This is a nice enhancement. What's unclear to me is why this is being hooked to both the
wp_head
andwp_footer
action. It doesn't seem like this function was designed to be run twice. In fact,wp_enqueue_style
doesn't even support anin_footer
param likewp_enqueue_script
,
I presume this is to print styles that were registered after the header action fires, similar to print_late_styles()
.
@spacedmonkey commented on PR #4500:
18 months ago
#8
@spacedmonkey commented on PR #4500:
18 months ago
#9
#10
@
18 months ago
- Resolution fixed deleted
- Status changed from closed to reopened
Just noting that this change has caused PHP Notices on WordPress.org. I'm unsure if this is a WordPress.org-specific oddity, or if it's a sign of something wider.
E_NOTICE: Undefined index: block-name-here in wp-includes/script-loader.php:2875 E_NOTICE: Trying to get property 'src' of non-object in wp-includes/script-loader.php:2875
In short, $wp_styles->registered[ $handle ]
is null
/ unset, but the $handle
is present within $wp_styles->queue
.
Previously this didn't throw a notice, as wp_styles()->get_data( $handle, 'path' )
returned false.
I believe the trigger is this code:
add_filter( 'wp_enqueue_scripts', function() { wp_deregister_style( 'wporg-block-name' ); }, 201 );
It appears that registering a style that is enqueued, doesn't actually dequeue the style, just removes the data and relies upon script-loader to skip over it when outputting on the page. It appears that WP_Scripts
relies upon WP_Dependencies::do_item()
to short-circuit when processing a no-longer-registered item:
https://github.com/WordPress/wordpress-develop/blob/e8846318cf9a4c8d012ae32b4de9a51655237a24/src/wp-includes/class-wp-dependencies.php#LL159C1-L161C2
re-opening this as a result.
#11
follow-up:
↓ 12
@
18 months ago
We need to change the following
foreach ( $wp_styles->queue as $handle ) {
$src = $wp_styles->registered[ $handle ]->src;
to
foreach ( $wp_styles->queue as $handle ) {
if( ! isset( $this->registered[ $handle ] ) ){
continue;
}
$src = $wp_styles->registered[ $handle ]->src;
There should also be a unit test for this .
Thoughts @dd32 @flixos90.
This ticket was mentioned in PR #4592 on WordPress/wordpress-develop by @kebbet.
18 months ago
#13
- Keywords has-unit-tests added
Draft, trying to write a test.
This ticket was mentioned in PR #4597 on WordPress/wordpress-develop by @spacedmonkey.
18 months ago
#14
Trac ticket: https://core.trac.wordpress.org/ticket/58394
#15
in reply to:
↑ 12
@
18 months ago
Replying to dd32:
Replying to spacedmonkey:
Thoughts
Works for me.
I have created a PR / patch for your review at #4597. This patch adds a unit tests as well, to ensure this bug will not happen again.
@spacedmonkey commented on PR #4597:
18 months ago
#16
@kebbet
This ticket was mentioned in Slack in #core by mukeshpanchal27. View the logs.
18 months ago
@spacedmonkey commented on PR #4597:
18 months ago
#19
Committed.
Trac ticket: https://core.trac.wordpress.org/ticket/58394