Opened 7 months ago
Last modified 5 months ago
#61234 new defect (bug)
Investigation Request: High Frequency of `hooked_block_types` Filter Calls
Reported by: | mreishus | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 6.5 |
Component: | Editor | Keywords: | |
Focuses: | performance | Cc: |
Description
I have identified a potential performance concern related to the hooked_block_types
filter in WordPress 6.5.3, particularly regarding its scalability when a site has a large number of blocks and custom patterns.
Steps to Reproduce:
- Environment Setup:
- Installed a completely blank WordPress.org 6.5.3 site using the default Twenty Twenty-Four theme.
- Customization:
- Installed and activated a custom plugin to count the number of times the
hooked_block_types
filter is applied. The plugin code is as follows:
- Installed and activated a custom plugin to count the number of times the
<?php /* Plugin Name: Hooked Block Types Counter Description: A simple plugin to count how many times the 'hooked_block_types' filter is applied. Version: 1.0 Author: Your Name */ function init_hooked_block_types_counter() { $GLOBALS['hooked_block_types_count'] = 0; } add_action('init', 'init_hooked_block_types_counter'); function increment_hooked_block_types_count($hooked_block_types, $relative_position, $anchor_block_type, $context) { $GLOBALS['hooked_block_types_count']++; return $hooked_block_types; // Returning the original list without modification } add_filter('hooked_block_types', 'increment_hooked_block_types_count', 10, 4); function log_hooked_block_types_count() { $count = $GLOBALS['hooked_block_types_count']; error_log("The 'hooked_block_types' filter was run $count times."); } add_action('shutdown', 'log_hooked_block_types_count'); ?>
- Initial Observation:
- Visiting the front page with the default Twenty Twenty-Four theme and no additional content shows:
[16-May-2024 22:03:09 UTC] The 'hooked_block_types' filter was run 526 times.
- Visiting the front page with the default Twenty Twenty-Four theme and no additional content shows:
- Adding Content:
- Using the Site Editor, edited the
Index
template by adding a Columns block, with a few Paragraph blocks in each column. - After saving the changes and visiting the home page again, it showed:
[16-May-2024 22:09:02 UTC] The 'hooked_block_types' filter was run 590 times.
- Using the Site Editor, edited the
Concerns:
- While the out-of-the-box performance might be acceptable, the issue scales significantly with added content.
- On a site with extensive custom patterns, I observed the filter being applied approximately 9,800 times.
- This scalability concern implies that functions hooked to
hooked_block_types
could potentially run thousands of times, which can have significant performance implications. - For example, Jetpack’s
sharing-button.php
hooks into this filter and runs the following check:( new Modules() )->is_active( 'sharedaddy' )
. Running such a check 10,000 times seems inefficient and could lead to performance bottlenecks. Authors writing code on this hook might be unaware it could be run thousands of times.
Reference:
Jetpack’s sharing-button.php:
https://github.com/Automattic/jetpack/blob/3631fb251d8734d656d818ed3c52cf71a2be204c/projects/plugins/jetpack/extensions/blocks/sharing-button/sharing-button.php#L224
Request:
- Investigate why the
hooked_block_types
filter is being applied so many times. - Consider optimizing the filter application to reduce redundancy and improve performance.
- Provide guidelines or best practices for plugin authors to avoid performance issues when hooking into
hooked_block_types
.
Thank you for looking into this matter. I believe addressing this will help improve the performance and scalability of WordPress sites, especially those with complex block structures and custom patterns.
Tangentially, we started an experiment a while ago that would replace the parsing/traversal/re-serialization with a streaming parser, which we hope will improve performance. We haven’t been working on this for a while but might get back to it some time after 6.6.