Make WordPress Core

Changeset 59213


Ignore:
Timestamp:
10/10/2024 09:05:04 PM (6 months ago)
Author:
flixos90
Message:

Themes: Improve performance of applying background image styles in theme.json.

The cost of using WP_Theme_JSON::get_block_nodes() for this in its original shape was high enough to lead to a performance regression. Therefore this changeset introduces a new option on the method that allows to bypass all logic except for retrieving the node paths, which is much faster and everything that this functionality needs.

Follow up to [58936].

Props mukesh27, flixos90, ramonopoly, joemcgill, andrewserong, swissspidy.
Fixes #61858.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-theme-json.php

    r58936 r59213  
    26912691     * @since 6.3.0 Refactored and stabilized selectors API.
    26922692     * @since 6.6.0 Added optional selectors and options for generating block nodes.
     2693     * @since 6.7.0 Added $include_node_paths_only option.
    26932694     *
    26942695     * @param array $theme_json The theme.json converted to an array.
     
    26972698     *     Optional. An array of options for now used for internal purposes only (may change without notice).
    26982699     *
    2699      *     @type bool   $include_block_style_variations  Includes nodes for block style variations. Default false.
     2700     *     @type bool $include_block_style_variations Include nodes for block style variations. Default false.
     2701     *     @type bool $include_node_paths_only        Return only block nodes node paths. Default false.
    27002702     * }
    27012703     * @return array The block nodes in theme.json.
     
    27132715        }
    27142716
     2717        $include_variations      = $options['include_block_style_variations'] ?? false;
     2718        $include_node_paths_only = $options['include_node_paths_only'] ?? false;
     2719
    27152720        foreach ( $theme_json['styles']['blocks'] as $name => $node ) {
    2716             $selector = null;
    2717             if ( isset( $selectors[ $name ]['selector'] ) ) {
    2718                 $selector = $selectors[ $name ]['selector'];
    2719             }
    2720 
    2721             $duotone_selector = null;
    2722             if ( isset( $selectors[ $name ]['duotone'] ) ) {
    2723                 $duotone_selector = $selectors[ $name ]['duotone'];
    2724             }
    2725 
    2726             $feature_selectors = null;
    2727             if ( isset( $selectors[ $name ]['selectors'] ) ) {
    2728                 $feature_selectors = $selectors[ $name ]['selectors'];
    2729             }
    2730 
    2731             $variation_selectors = array();
    2732             $include_variations  = $options['include_block_style_variations'] ?? false;
    2733             if ( $include_variations && isset( $node['variations'] ) ) {
    2734                 foreach ( $node['variations'] as $variation => $node ) {
    2735                     $variation_selectors[] = array(
    2736                         'path'     => array( 'styles', 'blocks', $name, 'variations', $variation ),
    2737                         'selector' => $selectors[ $name ]['styleVariations'][ $variation ],
    2738                     );
    2739                 }
    2740             }
    2741 
    2742             $nodes[] = array(
    2743                 'name'       => $name,
    2744                 'path'       => array( 'styles', 'blocks', $name ),
    2745                 'selector'   => $selector,
    2746                 'selectors'  => $feature_selectors,
    2747                 'duotone'    => $duotone_selector,
    2748                 'features'   => $feature_selectors,
    2749                 'variations' => $variation_selectors,
    2750                 'css'        => $selector,
    2751             );
     2721            $node_path = array( 'styles', 'blocks', $name );
     2722            if ( $include_node_paths_only ) {
     2723                $nodes[] = array(
     2724                    'path' => $node_path,
     2725                );
     2726            } else {
     2727                $selector = null;
     2728                if ( isset( $selectors[ $name ]['selector'] ) ) {
     2729                    $selector = $selectors[ $name ]['selector'];
     2730                }
     2731
     2732                $duotone_selector = null;
     2733                if ( isset( $selectors[ $name ]['duotone'] ) ) {
     2734                    $duotone_selector = $selectors[ $name ]['duotone'];
     2735                }
     2736
     2737                $feature_selectors = null;
     2738                if ( isset( $selectors[ $name ]['selectors'] ) ) {
     2739                    $feature_selectors = $selectors[ $name ]['selectors'];
     2740                }
     2741
     2742                $variation_selectors = array();
     2743                if ( $include_variations && isset( $node['variations'] ) ) {
     2744                    foreach ( $node['variations'] as $variation => $node ) {
     2745                        $variation_selectors[] = array(
     2746                            'path'     => array( 'styles', 'blocks', $name, 'variations', $variation ),
     2747                            'selector' => $selectors[ $name ]['styleVariations'][ $variation ],
     2748                        );
     2749                    }
     2750                }
     2751
     2752                $nodes[] = array(
     2753                    'name'       => $name,
     2754                    'path'       => $node_path,
     2755                    'selector'   => $selector,
     2756                    'selectors'  => $feature_selectors,
     2757                    'duotone'    => $duotone_selector,
     2758                    'features'   => $feature_selectors,
     2759                    'variations' => $variation_selectors,
     2760                    'css'        => $selector,
     2761                );
     2762            }
    27522763
    27532764            if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'] ) ) {
    27542765                foreach ( $theme_json['styles']['blocks'][ $name ]['elements'] as $element => $node ) {
     2766                    $node_path = array( 'styles', 'blocks', $name, 'elements', $element );
     2767                    if ( $include_node_paths_only ) {
     2768                        $nodes[] = array(
     2769                            'path' => $node_path,
     2770                        );
     2771                        continue;
     2772                    }
     2773
    27552774                    $nodes[] = array(
    2756                         'path'     => array( 'styles', 'blocks', $name, 'elements', $element ),
     2775                        'path'     => $node_path,
    27572776                        'selector' => $selectors[ $name ]['elements'][ $element ],
    27582777                    );
     
    27622781                        foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) {
    27632782                            if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'][ $element ][ $pseudo_selector ] ) ) {
     2783                                $node_path = array( 'styles', 'blocks', $name, 'elements', $element );
     2784                                if ( $include_node_paths_only ) {
     2785                                    $nodes[] = array(
     2786                                        'path' => $node_path,
     2787                                    );
     2788                                    continue;
     2789                                }
     2790
    27642791                                $nodes[] = array(
    2765                                     'path'     => array( 'styles', 'blocks', $name, 'elements', $element ),
     2792                                    'path'     => $node_path,
    27662793                                    'selector' => static::append_to_selector( $selectors[ $name ]['elements'][ $element ], $pseudo_selector ),
    27672794                                );
     
    32373264         * objects and represent unique definitions for the style.
    32383265         */
    3239         $style_nodes = static::get_styles_block_nodes();
     3266        $style_nodes = static::get_block_nodes(
     3267            $this->theme_json,
     3268            array(),
     3269            array( 'include_node_paths_only' => true )
     3270        );
    32403271        foreach ( $style_nodes as $style_node ) {
    32413272            $path = $style_node['path'];
  • trunk/tests/phpunit/tests/theme/wpThemeJson.php

    r58936 r59213  
    24422442
    24432443        $this->assertEqualSetsWithIndex( $expected, $actual );
     2444    }
     2445
     2446    /**
     2447     * This test covers `get_block_nodes` with the `$include_node_paths_only` option.
     2448     * When `true`, `$include_node_paths_only` should return only the paths of the block nodes.
     2449     *
     2450     * @ticket 61858
     2451     */
     2452    public function test_return_block_node_paths() {
     2453        $theme_json = new ReflectionClass( 'WP_Theme_JSON' );
     2454
     2455        $func = $theme_json->getMethod( 'get_block_nodes' );
     2456        $func->setAccessible( true );
     2457
     2458        $theme_json = array(
     2459            'version' => WP_Theme_JSON::LATEST_SCHEMA,
     2460            'styles'  => array(
     2461                'typography' => array(
     2462                    'fontSize' => '16px',
     2463                ),
     2464                'blocks'     => array(
     2465                    'core/button' => array(
     2466                        'color' => array(
     2467                            'background' => 'red',
     2468                        ),
     2469                    ),
     2470                    'core/group'  => array(
     2471                        'elements' => array(
     2472                            'link' => array(
     2473                                'color' => array(
     2474                                    'background' => 'blue',
     2475                                ),
     2476                            ),
     2477                        ),
     2478                    ),
     2479                ),
     2480            ),
     2481        );
     2482
     2483        $block_nodes = $func->invoke( null, $theme_json, array(), array( 'include_node_paths_only' => true ) );
     2484
     2485        $expected = array(
     2486            array(
     2487                'path' => array( 'styles', 'blocks', 'core/button' ),
     2488            ),
     2489            array(
     2490                'path' => array( 'styles', 'blocks', 'core/group' ),
     2491            ),
     2492            array(
     2493                'path' => array( 'styles', 'blocks', 'core/group', 'elements', 'link' ),
     2494            ),
     2495        );
     2496
     2497        $this->assertEquals( $expected, $block_nodes );
    24442498    }
    24452499
Note: See TracChangeset for help on using the changeset viewer.