Commit f53cbafcd97 for woocommerce
commit f53cbafcd9712180ecad5c26df12e723ae0ca6a6
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date: Tue Oct 13 09:03:45 2026 +0200
[Performance] Micro-optimizations package to compress blocks initialization time (#69720)
Micro-optimizes the block initialization hot path to minimize function/method calls and memory allocations where it makes sense.
diff --git a/plugins/woocommerce/changelog/performance-69369-blocks-hotpath-micro-optimizations b/plugins/woocommerce/changelog/performance-69369-blocks-hotpath-micro-optimizations
new file mode 100644
index 00000000000..7dfc5760c83
--- /dev/null
+++ b/plugins/woocommerce/changelog/performance-69369-blocks-hotpath-micro-optimizations
@@ -0,0 +1,4 @@
+Significance: patch
+Type: performance
+
+Micro-optimizations package to compress blocks initialization execution time.
diff --git a/plugins/woocommerce/includes/class-woocommerce.php b/plugins/woocommerce/includes/class-woocommerce.php
index 7dc2896b2e9..5d906af3923 100644
--- a/plugins/woocommerce/includes/class-woocommerce.php
+++ b/plugins/woocommerce/includes/class-woocommerce.php
@@ -1144,7 +1144,10 @@ final class WooCommerce {
* @return string
*/
public function plugin_path() {
- return untrailingslashit( plugin_dir_path( WC_PLUGIN_FILE ) );
+ static $plugin_path = null;
+ $plugin_path = $plugin_path ?? untrailingslashit( plugin_dir_path( WC_PLUGIN_FILE ) );
+
+ return $plugin_path;
}
/**
diff --git a/plugins/woocommerce/includes/widgets/class-wc-widget-price-filter.php b/plugins/woocommerce/includes/widgets/class-wc-widget-price-filter.php
index 31e2330d360..e2c3b51053e 100644
--- a/plugins/woocommerce/includes/widgets/class-wc-widget-price-filter.php
+++ b/plugins/woocommerce/includes/widgets/class-wc-widget-price-filter.php
@@ -35,12 +35,13 @@ class WC_Widget_Price_Filter extends WC_Widget {
);
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
- wp_register_script( 'wc-accounting', WC()->plugin_url() . '/assets/js/accounting/accounting' . $suffix . '.js', array( 'jquery' ), '0.4.2', true );
+ $plugin_url = WC()->plugin_url();
+ wp_register_script( 'wc-accounting', $plugin_url . '/assets/js/accounting/accounting' . $suffix . '.js', array( 'jquery' ), '0.4.2', true );
// This script is deprecated, but we need to register it for backwards compatibility.
// This can be removed in WooCommerce 10.5.0.
wp_register_script( 'accounting', false, array( 'wc-accounting' ), '0.4.2', true );
- wp_register_script( 'wc-jquery-ui-touchpunch', WC()->plugin_url() . '/assets/js/jquery-ui-touch-punch/jquery-ui-touch-punch' . $suffix . '.js', array( 'jquery-ui-slider' ), $version, true );
- wp_register_script( 'wc-price-slider', WC()->plugin_url() . '/assets/js/frontend/price-slider' . $suffix . '.js', array( 'jquery-ui-slider', 'wc-jquery-ui-touchpunch', 'wc-accounting' ), $version, true );
+ wp_register_script( 'wc-jquery-ui-touchpunch', $plugin_url . '/assets/js/jquery-ui-touch-punch/jquery-ui-touch-punch' . $suffix . '.js', array( 'jquery-ui-slider' ), $version, true );
+ wp_register_script( 'wc-price-slider', $plugin_url . '/assets/js/frontend/price-slider' . $suffix . '.js', array( 'jquery-ui-slider', 'wc-jquery-ui-touchpunch', 'wc-accounting' ), $version, true );
wp_localize_script(
'wc-price-slider',
'woocommerce_price_slider_params',
diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index 292d4002820..755c7780768 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -48609,12 +48609,6 @@ parameters:
count: 1
path: src/Blocks/BlockTypes/AbstractBlock.php
- -
- message: '#^Parameter \#1 \$object_or_string of function is_a expects object, array\|WP_Block given\.$#'
- identifier: argument.type
- count: 1
- path: src/Blocks/BlockTypes/AbstractBlock.php
-
-
message: '#^Parameter \#1 \$request of method WP_REST_Server\:\:get_namespace_index\(\) expects WP_REST_Request, array\<string, string\> given\.$#'
identifier: argument.type
diff --git a/plugins/woocommerce/src/Blocks/Assets/Api.php b/plugins/woocommerce/src/Blocks/Assets/Api.php
index c52e28a66cf..1a8c7076ee8 100644
--- a/plugins/woocommerce/src/Blocks/Assets/Api.php
+++ b/plugins/woocommerce/src/Blocks/Assets/Api.php
@@ -337,10 +337,9 @@ class Api {
* @param boolean $rtl Optional. Whether or not to register RTL styles.
*/
public function register_style( $handle, $relative_src, $deps = [], $media = 'all', $rtl = false ) {
- $filename = str_replace( plugins_url( '/', dirname( __DIR__ ) ), '', $relative_src );
- $src = $this->get_asset_url( $relative_src );
- $ver = $this->get_file_version( $filename );
- wp_register_style( $handle, $src, $deps, $ver, $media );
+ $src = $this->get_asset_url( $relative_src );
+ $version = $this->get_file_version( $relative_src );
+ wp_register_style( $handle, $src, $deps, $version, $media );
if ( $rtl ) {
wp_style_add_data( $handle, 'rtl', 'replace' );
diff --git a/plugins/woocommerce/src/Blocks/BlockTemplatesRegistry.php b/plugins/woocommerce/src/Blocks/BlockTemplatesRegistry.php
index 34116825a98..ac5717e4c08 100644
--- a/plugins/woocommerce/src/Blocks/BlockTemplatesRegistry.php
+++ b/plugins/woocommerce/src/Blocks/BlockTemplatesRegistry.php
@@ -87,21 +87,19 @@ class BlockTemplatesRegistry {
}
// Init all templates.
+ $directory = BlockTemplateUtils::get_templates_directory( 'wp_template' );
foreach ( $templates as $template ) {
$template->init();
- // Taxonomy templates are registered automatically by WordPress and
- // are made available through the Add Template menu.
+ // Taxonomy templates are registered automatically by WordPress and are made available through the Add Template menu.
if ( ! $template->is_taxonomy_template ) {
- $directory = BlockTemplateUtils::get_templates_directory( 'wp_template' );
- $template_file_path = $directory . '/' . $template::SLUG . '.html';
register_block_template(
'woocommerce//' . $template::SLUG,
array(
'title' => $template->get_template_title(),
'description' => $template->get_template_description(),
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
- 'content' => file_get_contents( $template_file_path ),
+ 'content' => file_get_contents( $directory . '/' . $template::SLUG . '.html' ),
)
);
}
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php b/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
index 279705aee62..de1b3266fe5 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
@@ -58,6 +58,13 @@ abstract class AbstractBlock {
*/
protected $integration_registry;
+ /**
+ * Whether unified block editor assets are enabled.
+ *
+ * @var bool
+ */
+ private bool $unified_editor_assets_enabled;
+
/**
* Constructor.
*
@@ -67,10 +74,11 @@ abstract class AbstractBlock {
* @param string $block_name Optionally set block name during construct.
*/
public function __construct( AssetApi $asset_api, AssetDataRegistry $asset_data_registry, IntegrationRegistry $integration_registry, $block_name = '' ) {
- $this->asset_api = $asset_api;
- $this->asset_data_registry = $asset_data_registry;
- $this->integration_registry = $integration_registry;
- $this->block_name = $block_name ? $block_name : $this->block_name;
+ $this->asset_api = $asset_api;
+ $this->asset_data_registry = $asset_data_registry;
+ $this->integration_registry = $integration_registry;
+ $this->block_name = $block_name ? $block_name : $this->block_name;
+ $this->unified_editor_assets_enabled = BlockEditorUnifiedAssets::is_enabled();
$this->initialize();
}
@@ -374,7 +382,7 @@ abstract class AbstractBlock {
* @return array|string
*/
protected function get_block_type_editor_script( $key = null ) {
- $script = BlockEditorUnifiedAssets::is_enabled()
+ $script = $this->unified_editor_assets_enabled
? array(
'handle' => 'wc-block-library',
'path' => $this->asset_api->get_block_asset_build_path( 'wc-block-library' ),
@@ -385,6 +393,7 @@ abstract class AbstractBlock {
'path' => $this->asset_api->get_block_asset_build_path( $this->block_name ),
'dependencies' => array( 'wc-blocks' ),
);
+
return $key ? $script[ $key ] : $script;
}
@@ -395,7 +404,7 @@ abstract class AbstractBlock {
* @return string|null
*/
protected function get_block_type_editor_style() {
- return BlockEditorUnifiedAssets::is_enabled() ? 'wc-block-library-style' : 'wc-blocks-editor-style';
+ return $this->unified_editor_assets_enabled ? 'wc-block-library-style' : 'wc-blocks-editor-style';
}
/**
@@ -460,7 +469,7 @@ abstract class AbstractBlock {
* @return array
*/
protected function parse_render_callback_attributes( $attributes ) {
- return is_a( $attributes, 'WP_Block' ) ? $attributes->attributes : $attributes;
+ return $attributes instanceof \WP_Block ? $attributes->attributes : $attributes;
}
/**
diff --git a/plugins/woocommerce/src/Blocks/Domain/Package.php b/plugins/woocommerce/src/Blocks/Domain/Package.php
index 53e150618c5..7efbf65349b 100644
--- a/plugins/woocommerce/src/Blocks/Domain/Package.php
+++ b/plugins/woocommerce/src/Blocks/Domain/Package.php
@@ -55,7 +55,7 @@ class Package {
$this->feature_gating = new FeatureGating();
}
$this->version = $version;
- $this->path = $plugin_path;
+ $this->path = trailingslashit( $plugin_path );
}
/**
@@ -98,7 +98,7 @@ class Package {
* @return string
*/
public function get_path( $relative_path = '' ) {
- return trailingslashit( $this->path ) . $relative_path;
+ return $this->path . $relative_path;
}
/**
diff --git a/plugins/woocommerce/src/Blocks/Integrations/IntegrationRegistry.php b/plugins/woocommerce/src/Blocks/Integrations/IntegrationRegistry.php
index 05c3412a518..585b08c7ed9 100644
--- a/plugins/woocommerce/src/Blocks/Integrations/IntegrationRegistry.php
+++ b/plugins/woocommerce/src/Blocks/Integrations/IntegrationRegistry.php
@@ -131,17 +131,12 @@ class IntegrationRegistry {
* @return string[]
*/
public function get_all_registered_editor_script_handles() {
- $script_handles = [];
- $registered_integrations = $this->get_all_registered();
-
- foreach ( $registered_integrations as $registered_integration ) {
- $script_handles = array_merge(
- $script_handles,
- $registered_integration->get_editor_script_handles()
- );
+ $script_handles = array( array() );
+ foreach ( $this->get_all_registered() as $registered_integration ) {
+ $script_handles[] = $registered_integration->get_editor_script_handles();
}
- return array_unique( array_filter( $script_handles ) );
+ return array_unique( array_filter( array_merge( ...$script_handles ) ) );
}
/**
@@ -150,17 +145,12 @@ class IntegrationRegistry {
* @return string[]
*/
public function get_all_registered_script_handles() {
- $script_handles = [];
- $registered_integrations = $this->get_all_registered();
-
- foreach ( $registered_integrations as $registered_integration ) {
- $script_handles = array_merge(
- $script_handles,
- $registered_integration->get_script_handles()
- );
+ $script_handles = array( array() );
+ foreach ( $this->get_all_registered() as $registered_integration ) {
+ $script_handles[] = $registered_integration->get_script_handles();
}
- return array_unique( array_filter( $script_handles ) );
+ return array_unique( array_filter( array_merge( ...$script_handles ) ) );
}
/**
@@ -169,10 +159,8 @@ class IntegrationRegistry {
* @return array
*/
public function get_all_registered_script_data() {
- $script_data = [];
- $registered_integrations = $this->get_all_registered();
-
- foreach ( $registered_integrations as $registered_integration ) {
+ $script_data = array();
+ foreach ( $this->get_all_registered() as $registered_integration ) {
$script_data[ $registered_integration->get_name() . '_data' ] = $registered_integration->get_script_data();
}
diff --git a/plugins/woocommerce/src/Blocks/Payments/Api.php b/plugins/woocommerce/src/Blocks/Payments/Api.php
index 82a36757438..fa7da034bc4 100644
--- a/plugins/woocommerce/src/Blocks/Payments/Api.php
+++ b/plugins/woocommerce/src/Blocks/Payments/Api.php
@@ -127,6 +127,16 @@ class Api {
* @param PaymentMethodRegistry $payment_method_registry Payment method registry instance.
*/
public function register_payment_method_integrations( PaymentMethodRegistry $payment_method_registry ) {
+ // Preload option caches to minimize future queries for options that do not yet exist or are not set to autoload.
+ wp_prime_option_caches(
+ array(
+ 'woocommerce_cheque_settings',
+ 'woocommerce_paypal_settings',
+ 'woocommerce_bacs_accounts',
+ 'woocommerce_cod_settings',
+ )
+ );
+
$payment_method_registry->register(
Package::container()->get( Cheque::class )
);
@@ -157,14 +167,7 @@ class Api {
$payment_method_scripts = $this->payment_method_registry->get_all_active_payment_method_script_dependencies();
foreach ( $payment_method_scripts as $payment_method_script ) {
- if (
- ! array_key_exists( $payment_method_script, $wp_scripts->registered ) ||
- ! property_exists( $wp_scripts->registered[ $payment_method_script ], 'deps' )
- ) {
- continue;
- }
- $deps = $wp_scripts->registered[ $payment_method_script ]->deps;
- foreach ( $deps as $dep ) {
+ foreach ( ( $wp_scripts->registered[ $payment_method_script ]->deps ?? array() ) as $dep ) { // @phpstan-ignore nullCoalesce.property (false-positive)
if ( ! wp_script_is( $dep, 'registered' ) ) {
$error_handle = $dep . '-dependency-error';
$error_message = sprintf(