Make WordPress Core

Changeset 54805


Ignore:
Timestamp:
11/11/2022 02:05:56 AM (4 years ago)
Author:
flixos90
Message:

Editor: Improve performance of WP_Theme_JSON class by reducing usage of expensive array functions.

In many scenarios array functions are more expensive than using simpler for or foreach loops.

This changeset results in roughly 4% faster wp_head execution time for both block themes and classic themes. While this may seem like a small win, it is a worthwhile enhancement and only one part of several other little performance tweaks which are being worked on to improve performance of theme.json parsing further.

Props aristath, desrosj, jrf, spacedmonkey.
Merges [54804] to the 6.1 branch.
Fixes #56974.
See #57067.

Location:
branches/6.1
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/6.1

  • branches/6.1/src/wp-includes/class-wp-theme-json.php

    r54800 r54805  
    462462                $class_name = '';
    463463
     464                // TODO: Replace array_key_exists() with isset() check once WordPress drops
     465                // support for PHP 5.6. See https://core.trac.wordpress.org/ticket/57067.
    464466                if ( array_key_exists( $element, static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES ) ) {
    465467                        $class_name = static::__EXPERIMENTAL_ELEMENT_CLASS_NAMES[ $element ];
     
    520522                foreach ( $nodes as $node ) {
    521523                        foreach ( static::PRESETS_METADATA as $preset_metadata ) {
    522                                 $path   = array_merge( $node['path'], $preset_metadata['path'] );
     524                                $path = $node['path'];
     525                                foreach ( $preset_metadata['path'] as $subpath ) {
     526                                        $path[] = $subpath;
     527                                }
    523528                                $preset = _wp_array_get( $this->theme_json, $path, null );
    524529                                if ( null !== $preset ) {
     
    609614                $styles_non_top_level = static::VALID_STYLES;
    610615                foreach ( array_keys( $styles_non_top_level ) as $section ) {
     616                        // array_key_exists() needs to be used instead of isset() because the value can be null.
    611617                        if ( array_key_exists( $section, $styles_non_top_level ) && is_array( $styles_non_top_level[ $section ] ) ) {
    612618                                foreach ( array_keys( $styles_non_top_level[ $section ] ) as $prop ) {
     
    632638                        $schema_styles_elements[ $element ] = $styles_non_top_level;
    633639
     640                        // TODO: Replace array_key_exists() with isset() check once WordPress drops
     641                        // support for PHP 5.6. See https://core.trac.wordpress.org/ticket/57067.
    634642                        if ( array_key_exists( $element, static::VALID_ELEMENT_PSEUDO_SELECTORS ) ) {
    635643                                foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) {
     
    12741282                        $selector = $metadata['selector'];
    12751283
    1276                         $node         = _wp_array_get( $this->theme_json, $metadata['path'], array() );
    1277                         $declarations = array_merge( static::compute_preset_vars( $node, $origins ), static::compute_theme_vars( $node ) );
     1284                        $node                    = _wp_array_get( $this->theme_json, $metadata['path'], array() );
     1285                        $declarations            = static::compute_preset_vars( $node, $origins );
     1286                        $theme_vars_declarations = static::compute_theme_vars( $node );
     1287                        foreach ( $theme_vars_declarations as $theme_vars_declaration ) {
     1288                                $declarations[] = $theme_vars_declaration;
     1289                        }
    12781290
    12791291                        $stylesheet .= static::to_ruleset( $selector, $declarations );
     
    16021614
    16031615                        if ( is_array( $value ) ) {
    1604                                 $new_prefix = $new_key . $token;
    1605                                 $result     = array_merge(
    1606                                         $result,
    1607                                         static::flatten_tree( $value, $new_prefix, $token )
    1608                                 );
     1616                                $new_prefix        = $new_key . $token;
     1617                                $flattened_subtree = static::flatten_tree( $value, $new_prefix, $token );
     1618                                foreach ( $flattened_subtree as $subtree_key => $subtree_value ) {
     1619                                        $result[ $subtree_key ] = $subtree_value;
     1620                                }
    16091621                        } else {
    16101622                                $result[ $new_key ] = $value;
     
    16681680                                $path_string = implode( '.', $value_path );
    16691681                                if (
     1682                                        // TODO: Replace array_key_exists() with isset() check once WordPress drops
     1683                                        // support for PHP 5.6. See https://core.trac.wordpress.org/ticket/57067.
    16701684                                        array_key_exists( $path_string, static::PROTECTED_PROPERTIES ) &&
    16711685                                        _wp_array_get( $settings, static::PROTECTED_PROPERTIES[ $path_string ], null ) === null
     
    17431757                 * For example: { "ref": "style.color.background" } => "#fff".
    17441758                 */
    1745                 if ( is_array( $value ) && array_key_exists( 'ref', $value ) ) {
     1759                if ( is_array( $value ) && isset( $value['ref'] ) ) {
    17461760                        $value_path = explode( '.', $value['ref'] );
    17471761                        $ref_value  = _wp_array_get( $theme_json, $value_path );
     
    17511765                        }
    17521766
    1753                         if ( is_array( $ref_value ) && array_key_exists( 'ref', $ref_value ) ) {
     1767                        if ( is_array( $ref_value ) && isset( $ref_value['ref'] ) ) {
    17541768                                $path_string      = json_encode( $path );
    17551769                                $ref_value_string = json_encode( $ref_value );
     
    18871901
    18881902                                // Handle any pseudo selectors for the element.
     1903                                // TODO: Replace array_key_exists() with isset() check once WordPress drops
     1904                                // support for PHP 5.6. See https://core.trac.wordpress.org/ticket/57067.
    18891905                                if ( array_key_exists( $element, static::VALID_ELEMENT_PSEUDO_SELECTORS ) ) {
    18901906                                        foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) {
     
    19061922                }
    19071923
    1908                 $nodes = array_merge( $nodes, static::get_block_nodes( $theme_json ) );
     1924                $block_nodes = static::get_block_nodes( $theme_json );
     1925                foreach ( $block_nodes as $block_node ) {
     1926                        $nodes[] = $block_node;
     1927                }
    19091928
    19101929                /**
     
    19832002
    19842003                                        // Handle any pseudo selectors for the element.
     2004                                        // TODO: Replace array_key_exists() with isset() check once WordPress drops
     2005                                        // support for PHP 5.6. See https://core.trac.wordpress.org/ticket/57067.
    19852006                                        if ( array_key_exists( $element, static::VALID_ELEMENT_PSEUDO_SELECTORS ) ) {
    19862007                                                foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) {
     
    20362057                                        // support features use the same custom selector.
    20372058                                        if ( isset( $feature_declarations[ $feature_selector ] ) ) {
    2038                                                 $feature_declarations[ $feature_selector ] = array_merge( $feature_declarations[ $feature_selector ], $new_feature_declarations );
     2059                                                foreach ( $new_feature_declarations as $new_feature_declaration ) {
     2060                                                        $feature_declarations[ $feature_selector ][] = $feature_declaration;
     2061                                                }
    20392062                                        } else {
    20402063                                                $feature_declarations[ $feature_selector ] = $new_feature_declarations;
     
    20602083                $element_pseudo_allowed = array();
    20612084
     2085                // TODO: Replace array_key_exists() with isset() check once WordPress drops
     2086                // support for PHP 5.6. See https://core.trac.wordpress.org/ticket/57067.
    20622087                if ( array_key_exists( $current_element, static::VALID_ELEMENT_PSEUDO_SELECTORS ) ) {
    20632088                        $element_pseudo_allowed = static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ];
     
    20852110                 */
    20862111                if ( $pseudo_selector && isset( $node[ $pseudo_selector ] ) &&
     2112                        // TODO: Replace array_key_exists() with isset() check once WordPress drops
     2113                        // support for PHP 5.6. See https://core.trac.wordpress.org/ticket/57067.
    20872114                        array_key_exists( $current_element, static::VALID_ELEMENT_PSEUDO_SELECTORS )
    20882115                        && in_array( $pseudo_selector, static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ], true )
     
    22842311                $slugs_global = static::get_default_slugs( $this->theme_json, array( 'settings' ) );
    22852312                foreach ( $nodes as $node ) {
    2286                         $slugs_node = static::get_default_slugs( $this->theme_json, $node['path'] );
    2287                         $slugs      = array_merge_recursive( $slugs_global, $slugs_node );
    2288 
    22892313                        // Replace the spacing.units.
    2290                         $path    = array_merge( $node['path'], array( 'spacing', 'units' ) );
     2314                        $path   = $node['path'];
     2315                        $path[] = 'spacing';
     2316                        $path[] = 'units';
     2317
    22912318                        $content = _wp_array_get( $incoming_data, $path, null );
    22922319                        if ( isset( $content ) ) {
     
    22992326
    23002327                                foreach ( static::VALID_ORIGINS as $origin ) {
    2301                                         $base_path = array_merge( $node['path'], $preset['path'] );
    2302                                         $path      = array_merge( $base_path, array( $origin ) );
    2303                                         $content   = _wp_array_get( $incoming_data, $path, null );
     2328                                        $base_path = $node['path'];
     2329                                        foreach ( $preset['path'] as $leaf ) {
     2330                                                $base_path[] = $leaf;
     2331                                        }
     2332
     2333                                        $path   = $base_path;
     2334                                        $path[] = $origin;
     2335
     2336                                        $content = _wp_array_get( $incoming_data, $path, null );
    23042337                                        if ( ! isset( $content ) ) {
    23052338                                                continue;
     
    23072340
    23082341                                        if ( 'theme' === $origin && $preset['use_default_names'] ) {
    2309                                                 foreach ( $content as &$item ) {
    2310                                                         if ( ! array_key_exists( 'name', $item ) ) {
     2342                                                foreach ( $content as $key => $item ) {
     2343                                                        if ( ! isset( $item['name'] ) ) {
    23112344                                                                $name = static::get_name_from_defaults( $item['slug'], $base_path );
    23122345                                                                if ( null !== $name ) {
    2313                                                                         $item['name'] = $name;
     2346                                                                        $content[ $key ]['name'] = $name;
    23142347                                                                }
    23152348                                                        }
     
    23232356                                                _wp_array_set( $this->theme_json, $path, $content );
    23242357                                        } else {
     2358                                                $slugs_node = static::get_default_slugs( $this->theme_json, $node['path'] );
     2359                                                $slugs      = array_merge_recursive( $slugs_global, $slugs_node );
     2360
    23252361                                                $slugs_for_preset = _wp_array_get( $slugs, $preset['path'], array() );
    23262362                                                $content          = static::filter_slugs( $content, $slugs_for_preset );
     
    24352471
    24362472                foreach ( static::PRESETS_METADATA as $metadata ) {
    2437                         $path   = array_merge( $node_path, $metadata['path'], array( 'default' ) );
     2473                        $path = $node_path;
     2474                        foreach ( $metadata['path'] as $leaf ) {
     2475                                $path[] = $leaf;
     2476                        }
     2477                        $path[] = 'default';
     2478
    24382479                        $preset = _wp_array_get( $data, $path, null );
    24392480                        if ( ! isset( $preset ) ) {
     
    24642505         */
    24652506        protected function get_name_from_defaults( $slug, $base_path ) {
    2466                 $path            = array_merge( $base_path, array( 'default' ) );
     2507                $path            = $base_path;
     2508                $path[]          = 'default';
    24672509                $default_content = _wp_array_get( $this->theme_json, $path, null );
    24682510                if ( ! $default_content ) {
     
    25402582                         * or insecure styles here.
    25412583                         */
     2584                        // TODO: Replace array_key_exists() with isset() check once WordPress drops
     2585                        // support for PHP 5.6. See https://core.trac.wordpress.org/ticket/57067.
    25422586                        if ( array_key_exists( $current_element, static::VALID_ELEMENT_PSEUDO_SELECTORS ) ) {
    25432587                                foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] as $pseudo_selector ) {
     
    25942638                foreach ( static::PRESETS_METADATA as $preset_metadata ) {
    25952639                        foreach ( static::VALID_ORIGINS as $origin ) {
    2596                                 $path_with_origin = array_merge( $preset_metadata['path'], array( $origin ) );
    2597                                 $presets          = _wp_array_get( $input, $path_with_origin, null );
     2640                                $path_with_origin   = $preset_metadata['path'];
     2641                                $path_with_origin[] = $origin;
     2642                                $presets            = _wp_array_get( $input, $path_with_origin, null );
    25982643                                if ( null === $presets ) {
    25992644                                        continue;
     
    28402885                foreach ( $nodes as $node ) {
    28412886                        foreach ( static::PRESETS_METADATA as $preset_metadata ) {
    2842                                 $path   = array_merge( $node['path'], $preset_metadata['path'] );
     2887                                $path = $node['path'];
     2888                                foreach ( $preset_metadata['path'] as $preset_metadata_path ) {
     2889                                        $path[] = $preset_metadata_path;
     2890                                }
    28432891                                $preset = _wp_array_get( $output, $path, null );
    28442892                                if ( null === $preset ) {
     
    28742922                        $all_opt_ins_are_set = true;
    28752923                        foreach ( static::APPEARANCE_TOOLS_OPT_INS as $opt_in_path ) {
    2876                                 $full_path = array_merge( $node['path'], $opt_in_path );
     2924                                $full_path = $node['path'];
     2925                                foreach ( $opt_in_path as $opt_in_path_item ) {
     2926                                        $full_path[] = $opt_in_path_item;
     2927                                }
    28772928                                // Use "unset prop" as a marker instead of "null" because
    28782929                                // "null" can be a valid value for some props (e.g. blockGap).
     
    28852936
    28862937                        if ( $all_opt_ins_are_set ) {
    2887                                 _wp_array_set( $output, array_merge( $node['path'], array( 'appearanceTools' ) ), true );
     2938                                $node_path_with_appearance_tools   = $node['path'];
     2939                                $node_path_with_appearance_tools[] = 'appearanceTools';
     2940                                _wp_array_set( $output, $node_path_with_appearance_tools, true );
    28882941                                foreach ( static::APPEARANCE_TOOLS_OPT_INS as $opt_in_path ) {
    2889                                         $full_path = array_merge( $node['path'], $opt_in_path );
     2942                                        $full_path = $node['path'];
     2943                                        foreach ( $opt_in_path as $opt_in_path_item ) {
     2944                                                $full_path[] = $opt_in_path_item;
     2945                                        }
    28902946                                        // Use "unset prop" as a marker instead of "null" because
    28912947                                        // "null" can be a valid value for some props (e.g. blockGap).
     
    30383094                }
    30393095
    3040                 $spacing_sizes = array_merge( $below_sizes, $above_sizes );
     3096                $spacing_sizes = $below_sizes;
     3097                foreach ( $above_sizes as $above_sizes_item ) {
     3098                        $spacing_sizes[] = $above_sizes_item;
     3099                }
    30413100
    30423101                // If there are 7 or less steps in the scale revert to numbers for labels instead of t-shirt sizes.
  • branches/6.1/tests/phpunit/tests/theme/wpThemeJson.php

    r54446 r54805  
    1010 *
    1111 * @group themes
     12 *
     13 * @covers WP_Theme_JSON
    1214 */
    13 
    1415class Tests_Theme_wpThemeJson extends WP_UnitTestCase {
    1516
Note: See TracChangeset for help on using the changeset viewer.