Make WordPress Core

Opened 4 weeks ago

Last modified 4 days ago

#62191 new enhancement

`WP_Theme_JSON::get_blocks_metadata()`: Check registered styles only upon change

Reported by: mreishus's profile mreishus Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Themes Keywords: has-patch
Focuses: performance Cc:

Description

Description

WP_Theme_JSON::get_blocks_metadata() is called frequently during page load. For example, my test site with the twentytwentyfour theme and WooCommerce installed calls it 121 times on a logged out homepage view.

The first time it runs, its computed data is stored on the static variable $blocks_metadata, allowing it to use a "fast path" for subsequent calls if no new blocks have been registered. However, each call to the "fast path" still checks for the possibility of new registered styles by looping over every possible block.

With a large number of registered blocks (e.g., 223 blocks with WooCommerce installed), the current implementation does a large number of unneeded checks for new styles on its "fast path".

By incrementing a counter inside the style registry whenever a style is registered or unregistered, then get_blocks_metadata() can know if it there is a need to process new styles or if it is already up to date.

Current Behavior

  • get_blocks_metadata() is called multiple times per request (e.g., 121 times on a sample homepage).
  • Even in the "fast path", it loops through all registered blocks to check for style updates.
  • With 223 registered blocks and 120 "fast path" calls, this results in 26,760 iterations (223 * 120) per page load.

Proposed Changes

  1. Add update tracking to WP_Block_Styles_Registry:
    • Introduce a $style_update_count property to track changes.
    • Implement a get_style_update_count() method to access this value.
    • Increment the count with each registration or unregistration of a block style.
  1. Optimize the "fast path" in get_blocks_metadata():
    • Check if there have been any style updates since the last call.
    • Only process style variations if changes have occurred.

Performance Impact

Testing Method:

  • Environment: WordPress site using the Twenty Twenty-Four theme with WooCommerce active
  • Procedure: Visited the home page 20 times for each scenario
  • Measurement: Time spent in the get_blocks_metadata() function
  • Result: Median of the 20 measurements

Scenarios and Results:

  1. Slow path:
    • Before: ~5.065 ms
    • After: ~5.075 ms
    • Change: Approximately 0.2% slower (negligible difference)
  1. Fast path:
    • Before: ~1.975 ms
    • After: ~0.24 ms
    • Improvement: Approximately 87.8% faster

This optimization saves approximately 1.74 ms per page load in this scenario. The impact could be more significant for sites with multiple plugins that register a large number of blocks.

This is a part of a larger effort to find performance penalties that scale with the number of blocks registered. I think cumulatively, several fixes in this area could make a difference when running big plugins.

Backwards Compatibility

This change should not affect backwards compatibility as it optimizes internal processing without changing the method's output or public API.

Testing

  1. Set up a WordPress site with the Twenty Twenty-Four theme and optionally, a plugin that registers a large number of blocks such as WooCommerce.
  2. Measure the execution time of get_blocks_metadata() before and after applying the patch.
  3. Verify that the functionality remains the same (e.g., all block styles are correctly applied).
  4. Test with various combinations of plugins that register multiple blocks to ensure the optimization works as expected.

Change History (2)

This ticket was mentioned in PR #7504 on WordPress/wordpress-develop by @mreishus.


4 weeks ago
#1

  • Keywords has-patch added

@mreishus commented on PR #7504:


4 days ago
#2

This is another one where the benefit is only realized after having a larger number of rendered blocks (2024 theme) and a larger number of registered blocks (WooCommerce or Jetpack plugin). However, I don't think it's making the base condition worse.

Note: See TracTickets for help on using tickets.