Opened 4 days ago
Last modified 24 hours ago
#65779 new defect (bug)
Speed up register_core_block_style_handles() $register_style check
| Reported by: | josephscott | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | General | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: | performance |
Description
The register_core_block_style_handles() function makes use of a static function $register_style - https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-includes/blocks/index.php#L97 - which has two in_array() checks.
For both of those in_array() checks there are two conditions that would allow us to swap them for isset() instead. First, the key we are looking for ( $style_path and $rtl_file ) is always a string. Second, we only care to find out if the key exists in the array.
To speed that up we could index $files and use isset() against that index:
$file_index = array_fill_keys( $files, true );
$register_style = static function ( $name, $filename, $style_handle ) use ( $blocks_url, $suffix, $wp_styles, $file_index ) {
...
if ( ! isset( $file_index[ $style_path ] ) ) {
...
if ( is_rtl() && isset( $file_index[ $rtl_file ] ) ) {
...
That saves us from having is_array() needing to walk the entire array looking to a match.
I confirmed that this speeds up register_core_block_style_handles() on my local WordPress 7.0.2 release. I tested by adding hrtime() to the stop and bottom of that function and writing the result with error_log(). Then I requested the Hello World post. This was M5 Macbook Pro.
Median for 10 runs with current is_array() code: 2.434125 ms
Median for 10 runs with isset() code: 1.352646 ms
That is a 44% reduction in how long register_core_block_style_handles() takes to finish. It hooks into init so it runs early and often.
I've got a patch for this and I'm having Claude go through tests to see what the current coverage looks like.
Change History (7)
This ticket was mentioned in PR #12798 on WordPress/wordpress-develop by @khokansardar.
4 days ago
#3
- Keywords has-patch added
register_core_block_style_handles() checked each candidate stylesheet against the core block CSS file list with in_array(). The closure runs three times per core block, so a request walked that 624-entry list roughly 270 times.
What the problem was:
- Two
in_array()scans per closure call, each walking the full file list. wp_normalize_path()ran before the early return, so the result was computed and discarded for every stylesheet that does not exist.
What the fix does:
- Indexes the file list once with
array_fill_keys()and usesisset()for both lookups. - Defers
wp_normalize_path()until after the early return.
Approach and why:
- Both lookup keys are always non-numeric strings ending in
.css, so key lookup is equivalent to the strictin_array()it replaces. Verified against the real file list: 624 files, 0 keys coerced to integers, 0 lookup mismatches againstin_array( ..., true ), including numeric and empty probes. - The transient payload is unchanged, so no cache compatibility concern.
- No new tests: the existing data provider already covers all three changed paths (157 registrations with a path, 188 early returns, 156 RTL variants).
Trac ticket: https://core.trac.wordpress.org/ticket/65779
## Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Ticket analysis and tests. All changes were reviewed and validated by me.
This ticket was mentioned in PR #12802 on WordPress/wordpress-develop by @josephscott.
3 days ago
#4
- Keywords has-unit-tests added
https://core.trac.wordpress.org/ticket/65779
AI assistance: Yes
Tool(s): Claude
Model(s): Opus 5
Used for: Exploration, validating ideas for improvement, and writing the tests
-->
@mukesh27 commented on PR #12798:
34 hours ago
#5
Thanks for the PR!
Closing in favour of #12802.
@mukesh27 commented on PR #12802:
34 hours ago
#6
Additional props for folks who works on 12798
Props khokansardar, irozum.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
One other small thing while I'm in here - moving
$path = wp_normalize_path( BLOCKS_PATH . $style_path );to be after the earlyreturncondition. It doesn't get used until after the earlyreturn, so there is not point in doing that work unless we are actually going to use it.