Skip to content

Commit

Permalink
Editor: Reduce the use of the _wp_array_get() function to improve p…
Browse files Browse the repository at this point in the history
…erformance.

`_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:
* [WordPress/gutenberg#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
  • Loading branch information
SergeyBiryukov authored and Anton Vlasenko committed Sep 29, 2023
1 parent 6d35429 commit f9deae4
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 105 deletions.
12 changes: 9 additions & 3 deletions src/wp-includes/block-supports/background.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,15 @@ function wp_render_background_support( $block_content, $block ) {
return $block_content;
}

$background_image_source = _wp_array_get( $block_attributes, array( 'style', 'background', 'backgroundImage', 'source' ), null );
$background_image_url = _wp_array_get( $block_attributes, array( 'style', 'background', 'backgroundImage', 'url' ), null );
$background_size = _wp_array_get( $block_attributes, array( 'style', 'background', 'backgroundSize' ), 'cover' );
$background_image_source = isset( $block_attributes['style']['background']['backgroundImage']['source'] )
? $block_attributes['style']['background']['backgroundImage']['source']
: null;
$background_image_url = isset( $block_attributes['style']['background']['backgroundImage']['url'] )
? $block_attributes['style']['background']['backgroundImage']['url']
: null;
$background_size = isset( $block_attributes['style']['background']['backgroundSize'] )
? $block_attributes['style']['background']['backgroundSize']
: 'cover';

$background_block_styles = array();

Expand Down
16 changes: 9 additions & 7 deletions src/wp-includes/block-supports/border.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ function wp_apply_border_support( $block_type, $block_attributes ) {
! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' )
) {
$preset_border_color = array_key_exists( 'borderColor', $block_attributes ) ? "var:preset|color|{$block_attributes['borderColor']}" : null;
$custom_border_color = _wp_array_get( $block_attributes, array( 'style', 'border', 'color' ), null );
$custom_border_color = isset( $block_attributes['style']['border']['color'] ) ? $block_attributes['style']['border']['color'] : null;
$border_block_styles['color'] = $preset_border_color ? $preset_border_color : $custom_border_color;
}

// Generates styles for individual border sides.
if ( $has_border_color_support || $has_border_width_support ) {
foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) {
$border = _wp_array_get( $block_attributes, array( 'style', 'border', $side ), null );
$border = isset( $block_attributes['style']['border'][ $side ] ) ? $block_attributes['style']['border'][ $side ] : null;
$border_side_values = array(
'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ? $border['width'] : null,
'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ? $border['color'] : null,
Expand Down Expand Up @@ -152,11 +152,13 @@ function wp_apply_border_support( $block_type, $block_attributes ) {
*/
function wp_has_border_feature_support( $block_type, $feature, $default_value = false ) {
// Check if all border support features have been opted into via `"__experimentalBorder": true`.
if (
property_exists( $block_type, 'supports' ) &&
( true === _wp_array_get( $block_type->supports, array( '__experimentalBorder' ), $default_value ) )
) {
return true;
if ( property_exists( $block_type, 'supports' ) ) {
$block_type_supports_border = isset( $block_type->supports['__experimentalBorder'] )
? $block_type->supports['__experimentalBorder']
: $default_value;
if ( true === $block_type_supports_border ) {
return true;
}
}

// Check if the specific feature has been opted into individually
Expand Down
39 changes: 25 additions & 14 deletions src/wp-includes/block-supports/colors.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,20 @@
* @param WP_Block_Type $block_type Block Type.
*/
function wp_register_colors_support( $block_type ) {
$color_support = property_exists( $block_type, 'supports' ) ? _wp_array_get( $block_type->supports, array( 'color' ), false ) : false;
$has_text_colors_support = true === $color_support || ( is_array( $color_support ) && _wp_array_get( $color_support, array( 'text' ), true ) );
$has_background_colors_support = true === $color_support || ( is_array( $color_support ) && _wp_array_get( $color_support, array( 'background' ), true ) );
$has_gradients_support = _wp_array_get( $color_support, array( 'gradients' ), false );
$has_link_colors_support = _wp_array_get( $color_support, array( 'link' ), false );
$has_button_colors_support = _wp_array_get( $color_support, array( 'button' ), false );
$has_heading_colors_support = _wp_array_get( $color_support, array( 'heading' ), false );
$color_support = false;
if ( property_exists( $block_type, 'supports' ) ) {
$color_support = isset( $block_type->supports['color'] ) ? $block_type->supports['color'] : false;
}
$has_text_colors_support = true === $color_support ||
( isset( $color_support['text'] ) && $color_support['text'] ) ||
( is_array( $color_support ) && ! isset( $color_support['text'] ) );
$has_background_colors_support = true === $color_support ||
( isset( $color_support['background'] ) && $color_support['background'] ) ||
( is_array( $color_support ) && ! isset( $color_support['background'] ) );
$has_gradients_support = isset( $color_support['gradients'] ) ? $color_support['gradients'] : false;
$has_link_colors_support = isset( $color_support['link'] ) ? $color_support['link'] : false;
$has_button_colors_support = isset( $color_support['button'] ) ? $color_support['button'] : false;
$has_heading_colors_support = isset( $color_support['heading'] ) ? $color_support['heading'] : false;
$has_color_support = $has_text_colors_support ||
$has_background_colors_support ||
$has_gradients_support ||
Expand Down Expand Up @@ -74,7 +81,7 @@ function wp_register_colors_support( $block_type ) {
* @return array Colors CSS classes and inline styles.
*/
function wp_apply_colors_support( $block_type, $block_attributes ) {
$color_support = _wp_array_get( $block_type->supports, array( 'color' ), false );
$color_support = isset( $block_type->supports['color'] ) ? $block_type->supports['color'] : false;

if (
is_array( $color_support ) &&
Expand All @@ -83,29 +90,33 @@ function wp_apply_colors_support( $block_type, $block_attributes ) {
return array();
}

$has_text_colors_support = true === $color_support || ( is_array( $color_support ) && _wp_array_get( $color_support, array( 'text' ), true ) );
$has_background_colors_support = true === $color_support || ( is_array( $color_support ) && _wp_array_get( $color_support, array( 'background' ), true ) );
$has_gradients_support = _wp_array_get( $color_support, array( 'gradients' ), false );
$has_text_colors_support = true === $color_support ||
( isset( $color_support['text'] ) && $color_support['text'] ) ||
( is_array( $color_support ) && ! isset( $color_support['text'] ) );
$has_background_colors_support = true === $color_support ||
( isset( $color_support['background'] ) && $color_support['background'] ) ||
( is_array( $color_support ) && ! isset( $color_support['background'] ) );
$has_gradients_support = isset( $color_support['gradients'] ) ? $color_support['gradients'] : false;
$color_block_styles = array();

// Text colors.
if ( $has_text_colors_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'text' ) ) {
$preset_text_color = array_key_exists( 'textColor', $block_attributes ) ? "var:preset|color|{$block_attributes['textColor']}" : null;
$custom_text_color = _wp_array_get( $block_attributes, array( 'style', 'color', 'text' ), null );
$custom_text_color = isset( $block_attributes['style']['color']['text'] ) ? $block_attributes['style']['color']['text'] : null;
$color_block_styles['text'] = $preset_text_color ? $preset_text_color : $custom_text_color;
}

// Background colors.
if ( $has_background_colors_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'background' ) ) {
$preset_background_color = array_key_exists( 'backgroundColor', $block_attributes ) ? "var:preset|color|{$block_attributes['backgroundColor']}" : null;
$custom_background_color = _wp_array_get( $block_attributes, array( 'style', 'color', 'background' ), null );
$custom_background_color = isset( $block_attributes['style']['color']['background'] ) ? $block_attributes['style']['color']['background'] : null;
$color_block_styles['background'] = $preset_background_color ? $preset_background_color : $custom_background_color;
}

// Gradients.
if ( $has_gradients_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'gradients' ) ) {
$preset_gradient_color = array_key_exists( 'gradient', $block_attributes ) ? "var:preset|gradient|{$block_attributes['gradient']}" : null;
$custom_gradient_color = _wp_array_get( $block_attributes, array( 'style', 'color', 'gradient' ), null );
$custom_gradient_color = isset( $block_attributes['style']['color']['gradient'] ) ? $block_attributes['style']['color']['gradient'] : null;
$color_block_styles['gradient'] = $preset_gradient_color ? $preset_gradient_color : $custom_gradient_color;
}

Expand Down
9 changes: 7 additions & 2 deletions src/wp-includes/block-supports/dimensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,13 @@ function wp_apply_dimensions_support( $block_type, $block_attributes ) { // phpc

$skip_min_height = wp_should_skip_block_supports_serialization( $block_type, 'dimensions', 'minHeight' );
$dimensions_block_styles = array();
$dimensions_block_styles['minHeight'] = $has_min_height_support && ! $skip_min_height ? _wp_array_get( $block_styles, array( 'dimensions', 'minHeight' ), null ) : null;
$styles = wp_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) );
$dimensions_block_styles['minHeight'] = null;
if ( $has_min_height_support && ! $skip_min_height ) {
$dimensions_block_styles['minHeight'] = isset( $block_styles['dimensions']['minHeight'] )
? $block_styles['dimensions']['minHeight']
: null;
}
$styles = wp_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) );

if ( ! empty( $styles['css'] ) ) {
$attributes['style'] = $styles['css'];
Expand Down
6 changes: 4 additions & 2 deletions src/wp-includes/block-supports/elements.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function wp_render_elements_support_styles( $pre_render, $block ) {
continue;
}

$element_style_object = _wp_array_get( $element_block_styles, array( $element_type ), null );
$element_style_object = isset( $element_block_styles[ $element_type ] ) ? $element_block_styles[ $element_type ] : null;

// Process primary element type styles.
if ( $element_style_object ) {
Expand All @@ -201,7 +201,9 @@ function wp_render_elements_support_styles( $pre_render, $block ) {
// Process related elements e.g. h1-h6 for headings.
if ( isset( $element_config['elements'] ) ) {
foreach ( $element_config['elements'] as $element ) {
$element_style_object = _wp_array_get( $element_block_styles, array( $element ), null );
$element_style_object = isset( $element_block_styles[ $element ] )
? $element_block_styles[ $element ]
: null;

if ( $element_style_object ) {
wp_style_engine_get_styles(
Expand Down
49 changes: 38 additions & 11 deletions src/wp-includes/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,10 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false
$gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' );

foreach ( $gap_sides as $gap_side ) {
$process_value = is_string( $gap_value ) ? $gap_value : _wp_array_get( $gap_value, array( $gap_side ), $fallback_gap_value );
$process_value = $gap_value;
if ( is_array( $gap_value ) ) {
$process_value = isset( $gap_value[ $gap_side ] ) ? $gap_value[ $gap_side ] : $fallback_gap_value;
}
// Get spacing CSS variable from preset value if provided.
if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) {
$index_to_splice = strrpos( $process_value, '|' ) + 1;
Expand Down Expand Up @@ -495,7 +498,10 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false
$gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' );

foreach ( $gap_sides as $gap_side ) {
$process_value = is_string( $gap_value ) ? $gap_value : _wp_array_get( $gap_value, array( $gap_side ), $fallback_gap_value );
$process_value = $gap_value;
if ( is_array( $gap_value ) ) {
$process_value = isset( $gap_value[ $gap_side ] ) ? $gap_value[ $gap_side ] : $fallback_gap_value;
}
// Get spacing CSS variable from preset value if provided.
if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) {
$index_to_splice = strrpos( $process_value, '|' ) + 1;
Expand Down Expand Up @@ -612,8 +618,15 @@ function wp_render_layout_support_flag( $block_content, $block ) {
}

$global_settings = wp_get_global_settings();
$fallback_layout = ! empty( _wp_array_get( $block_type->supports, array( 'layout', 'default' ), array() ) ) ? _wp_array_get( $block_type->supports, array( 'layout', 'default' ), array() ) : _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() );
$used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $fallback_layout;
$fallback_layout = isset( $block_type->supports['layout']['default'] )
? $block_type->supports['layout']['default']
: array();
if ( empty( $fallback_layout ) ) {
$fallback_layout = isset( $block_type->supports['__experimentalLayout']['default'] )
? $block_type->supports['__experimentalLayout']['default']
: array();
}
$used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $fallback_layout;

$class_names = array();
$layout_definitions = wp_get_layout_definitions();
Expand All @@ -624,7 +637,9 @@ function wp_render_layout_support_flag( $block_content, $block ) {
$used_layout['type'] = 'constrained';
}

$root_padding_aware_alignments = _wp_array_get( $global_settings, array( 'useRootPaddingAwareAlignments' ), false );
$root_padding_aware_alignments = isset( $global_settings['useRootPaddingAwareAlignments'] )
? $global_settings['useRootPaddingAwareAlignments']
: false;

if (
$root_padding_aware_alignments &&
Expand Down Expand Up @@ -654,9 +669,13 @@ function wp_render_layout_support_flag( $block_content, $block ) {

// Get classname for layout type.
if ( isset( $used_layout['type'] ) ) {
$layout_classname = _wp_array_get( $layout_definitions, array( $used_layout['type'], 'className' ), '' );
$layout_classname = isset( $layout_definitions[ $used_layout['type'] ]['className'] )
? $layout_definitions[ $used_layout['type'] ]['className']
: '';
} else {
$layout_classname = _wp_array_get( $layout_definitions, array( 'default', 'className' ), '' );
$layout_classname = isset( $layout_definitions['default']['className'] )
? $layout_definitions['default']['className']
: '';
}

if ( $layout_classname && is_string( $layout_classname ) ) {
Expand All @@ -669,7 +688,9 @@ function wp_render_layout_support_flag( $block_content, $block ) {
*/
if ( ! current_theme_supports( 'disable-layout-styles' ) ) {

$gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) );
$gap_value = isset( $block['attrs']['style']['spacing']['blockGap'] )
? $block['attrs']['style']['spacing']['blockGap']
: null;
/*
* Skip if gap value contains unsupported characters.
* Regex for CSS value borrowed from `safecss_filter_attr`, and used here
Expand All @@ -683,16 +704,22 @@ function wp_render_layout_support_flag( $block_content, $block ) {
$gap_value = $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value;
}

$fallback_gap_value = _wp_array_get( $block_type->supports, array( 'spacing', 'blockGap', '__experimentalDefault' ), '0.5em' );
$block_spacing = _wp_array_get( $block, array( 'attrs', 'style', 'spacing' ), null );
$fallback_gap_value = isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] )
? $block_type->supports['spacing']['blockGap']['__experimentalDefault']
: '0.5em';
$block_spacing = isset( $block['attrs']['style']['spacing'] )
? $block['attrs']['style']['spacing']
: null;

/*
* If a block's block.json skips serialization for spacing or spacing.blockGap,
* don't apply the user-defined value to the styles.
*/
$should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' );

$block_gap = _wp_array_get( $global_settings, array( 'spacing', 'blockGap' ), null );
$block_gap = isset( $global_settings['spacing']['blockGap'] )
? $global_settings['spacing']['blockGap']
: null;
$has_block_gap_support = isset( $block_gap );

$style = wp_get_layout_style(
Expand Down
10 changes: 5 additions & 5 deletions src/wp-includes/block-supports/position.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ function wp_render_position_support( $block_content, $block ) {
}

$global_settings = wp_get_global_settings();
$theme_has_sticky_support = _wp_array_get( $global_settings, array( 'position', 'sticky' ), false );
$theme_has_fixed_support = _wp_array_get( $global_settings, array( 'position', 'fixed' ), false );
$theme_has_sticky_support = isset( $global_settings['position']['sticky'] ) ? $global_settings['position']['sticky'] : false;
$theme_has_fixed_support = isset( $global_settings['position']['fixed'] ) ? $global_settings['position']['fixed'] : false;

// Only allow output for position types that the theme supports.
$allowed_position_types = array();
Expand All @@ -63,11 +63,11 @@ function wp_render_position_support( $block_content, $block ) {
$allowed_position_types[] = 'fixed';
}

$style_attribute = _wp_array_get( $block, array( 'attrs', 'style' ), null );
$style_attribute = isset( $block['attrs']['style'] ) ? $block['attrs']['style'] : null;
$class_name = wp_unique_id( 'wp-container-' );
$selector = ".$class_name";
$position_styles = array();
$position_type = _wp_array_get( $style_attribute, array( 'position', 'type' ), '' );
$position_type = isset( $style_attribute['position']['type'] ) ? $style_attribute['position']['type'] : '';
$wrapper_classes = array();

if (
Expand All @@ -78,7 +78,7 @@ function wp_render_position_support( $block_content, $block ) {
$sides = array( 'top', 'right', 'bottom', 'left' );

foreach ( $sides as $side ) {
$side_value = _wp_array_get( $style_attribute, array( 'position', $side ) );
$side_value = isset( $style_attribute['position'][ $side ] ) ? $style_attribute['position'][ $side ] : null;
if ( null !== $side_value ) {
/*
* For fixed or sticky top positions,
Expand Down
4 changes: 2 additions & 2 deletions src/wp-includes/block-supports/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function _wp_add_block_level_presets_class( $block_content, $block ) {
}

// return early if no settings are found on the block attributes.
$block_settings = _wp_array_get( $block, array( 'attrs', 'settings' ), null );
$block_settings = isset( $block['attrs']['settings'] ) ? $block['attrs']['settings'] : null;
if ( empty( $block_settings ) ) {
return $block_content;
}
Expand Down Expand Up @@ -82,7 +82,7 @@ function _wp_add_block_level_preset_styles( $pre_render, $block ) {
}

// return early if no settings are found on the block attributes.
$block_settings = _wp_array_get( $block, array( 'attrs', 'settings' ), null );
$block_settings = isset( $block['attrs']['settings'] ) ? $block['attrs']['settings'] : null;
if ( empty( $block_settings ) ) {
return null;
}
Expand Down
Loading

0 comments on commit f9deae4

Please sign in to comment.