Make WordPress Core

Changeset 54805


Ignore:
Timestamp:
11/11/2022 02:05:56 AM (23 months 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.