Editor: Reduce the use of the _wp_array_get() function to improve performance.

`_wp_array_get()` is an expensive function, and it's called thousands of times on each page view on the front end. While the function performance was slightly improved in #58376, it is still called more times than it should be.

This commit aims to further optimize its usage:
* In many cases, `_wp_array_get()` can be replaced with a much simpler and faster `isset()` check.
* The `isset()` function is capable of checking nested arrays, so `isset( $foo['a']['b']['c'] )` will return false even if `$foo['a']` is unset, without throwing any errors or warnings.
* When `_wp_array_get()` cannot be directly replaced with `isset()`, it would be good practice to wrap it in an `isset()` function so that `_wp_array_get()` only runs when it needs to.

Original PR from Gutenberg repository:
* [https://github.com/WordPress/gutenberg/pull/51116 #51116 Performance improvement: Reduce the use of the _wp_array_get() function]

Follow-up to [55851], [56382].

Props aristath, jrf, spacedmonkey, mukesh27, swissspidy, hellofromTonya.
Fixes #59405.

git-svn-id: https://develop.svn.wordpress.org/trunk@56709 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Sergey Biryukov
2023-09-26 13:45:23 +00:00
parent a52838d1b1
commit e77aaf1bae
15 changed files with 189 additions and 105 deletions

View File

@@ -923,7 +923,9 @@ class WP_Theme_JSON {
// Keep backwards compatibility for support.color.__experimentalDuotone.
if ( null === $duotone_selector ) {
$duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), null );
$duotone_support = isset( $block_type->supports['color']['__experimentalDuotone'] )
? $block_type->supports['color']['__experimentalDuotone']
: null;
if ( $duotone_support ) {
$root_selector = wp_get_block_css_selector( $block_type );
@@ -1160,12 +1162,14 @@ class WP_Theme_JSON {
*/
public function get_custom_css() {
// Add the global styles root CSS.
$stylesheet = _wp_array_get( $this->theme_json, array( 'styles', 'css' ), '' );
$stylesheet = isset( $this->theme_json['styles']['css'] ) ? $this->theme_json['styles']['css'] : '';
// Add the global styles block CSS.
if ( isset( $this->theme_json['styles']['blocks'] ) ) {
foreach ( $this->theme_json['styles']['blocks'] as $name => $node ) {
$custom_block_css = _wp_array_get( $this->theme_json, array( 'styles', 'blocks', $name, 'css' ) );
$custom_block_css = isset( $this->theme_json['styles']['blocks'][ $name ]['css'] )
? $this->theme_json['styles']['blocks'][ $name ]['css']
: null;
if ( $custom_block_css ) {
$selector = static::$blocks_metadata[ $name ]['selector'];
$stylesheet .= $this->process_blocks_custom_css( $custom_block_css, $selector );
@@ -1284,7 +1288,7 @@ class WP_Theme_JSON {
}
$selector = isset( $block_metadata['selector'] ) ? $block_metadata['selector'] : '';
$has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null;
$has_block_gap_support = isset( $this->theme_json['settings']['spacing']['blockGap'] );
$has_fallback_gap_support = ! $has_block_gap_support; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback gap styles support.
$node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() );
$layout_definitions = wp_get_layout_definitions();
@@ -1300,7 +1304,9 @@ class WP_Theme_JSON {
if ( ! $has_block_gap_support ) {
$block_gap_value = static::ROOT_BLOCK_SELECTOR === $selector ? '0.5em' : null;
if ( ! empty( $block_type ) ) {
$block_gap_value = _wp_array_get( $block_type->supports, array( 'spacing', 'blockGap', '__experimentalDefault' ), null );
$block_gap_value = isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] )
? $block_type->supports['spacing']['blockGap']['__experimentalDefault']
: null;
}
} else {
$block_gap_value = static::get_property_value( $node, array( 'spacing', 'blockGap' ) );
@@ -1326,8 +1332,8 @@ class WP_Theme_JSON {
continue;
}
$class_name = _wp_array_get( $layout_definition, array( 'className' ), false );
$spacing_rules = _wp_array_get( $layout_definition, array( 'spacingStyles' ), array() );
$class_name = isset( $layout_definition['className'] ) ? $layout_definition['className'] : false;
$spacing_rules = isset( $layout_definition['spacingStyles'] ) ? $layout_definition['spacingStyles'] : array();
if (
! empty( $class_name ) &&
@@ -1383,8 +1389,8 @@ class WP_Theme_JSON {
) {
$valid_display_modes = array( 'block', 'flex', 'grid' );
foreach ( $layout_definitions as $layout_definition ) {
$class_name = _wp_array_get( $layout_definition, array( 'className' ), false );
$base_style_rules = _wp_array_get( $layout_definition, array( 'baseStyles' ), array() );
$class_name = isset( $layout_definition['className'] ) ? $layout_definition['className'] : false;
$base_style_rules = isset( $layout_definition['baseStyles'] ) ? $layout_definition['baseStyles'] : array();
if (
! empty( $class_name ) &&
@@ -1812,7 +1818,7 @@ class WP_Theme_JSON {
*/
protected static function compute_theme_vars( $settings ) {
$declarations = array();
$custom_values = _wp_array_get( $settings, array( 'custom' ), array() );
$custom_values = isset( $settings['custom'] ) ? $settings['custom'] : array();
$css_vars = static::flatten_tree( $custom_values );
foreach ( $css_vars as $key => $value ) {
$declarations[] = array(
@@ -2326,7 +2332,7 @@ class WP_Theme_JSON {
$node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() );
$use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments'];
$selector = $block_metadata['selector'];
$settings = _wp_array_get( $this->theme_json, array( 'settings' ) );
$settings = isset( $this->theme_json['settings'] ) ? $this->theme_json['settings'] : array();
$feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $node );
// If there are style variations, generate the declarations for them, including any feature selectors the block may have.
@@ -2466,7 +2472,7 @@ class WP_Theme_JSON {
*/
public function get_root_layout_rules( $selector, $block_metadata ) {
$css = '';
$settings = _wp_array_get( $this->theme_json, array( 'settings' ) );
$settings = isset( $this->theme_json['settings'] ) ? $this->theme_json['settings'] : array();
$use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments'];
/*
@@ -2515,8 +2521,8 @@ class WP_Theme_JSON {
$css .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }';
$css .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }';
$block_gap_value = _wp_array_get( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ), '0.5em' );
$has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null;
$block_gap_value = isset( $this->theme_json['styles']['spacing']['blockGap'] ) ? $this->theme_json['styles']['spacing']['blockGap'] : '0.5em';
$has_block_gap_support = isset( $this->theme_json['settings']['spacing']['blockGap'] );
if ( $has_block_gap_support ) {
$block_gap_value = static::get_property_value( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ) );
$css .= ":where(.wp-site-blocks) > * { margin-block-start: $block_gap_value; margin-block-end: 0; }";
@@ -3355,7 +3361,9 @@ class WP_Theme_JSON {
* @return null|void
*/
public function set_spacing_sizes() {
$spacing_scale = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'spacingScale' ), array() );
$spacing_scale = isset( $this->theme_json['settings']['spacing']['spacingScale'] )
? $this->theme_json['settings']['spacing']['spacingScale']
: array();
if ( ! isset( $spacing_scale['steps'] )
|| ! is_numeric( $spacing_scale['steps'] )
@@ -3594,7 +3602,9 @@ class WP_Theme_JSON {
return $declarations;
}
$settings = _wp_array_get( $this->theme_json, array( 'settings' ) );
$settings = isset( $this->theme_json['settings'] )
? $this->theme_json['settings']
: array();
foreach ( $metadata['selectors'] as $feature => $feature_selectors ) {
/*