Skip to content

Commit 655125a

Browse files
committed
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. git-svn-id: https://develop.svn.wordpress.org/trunk@59213 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 31ce381 commit 655125a

File tree

2 files changed

+120
-35
lines changed

2 files changed

+120
-35
lines changed

src/wp-includes/class-wp-theme-json.php

Lines changed: 66 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,13 +2690,15 @@ private static function update_separator_declarations( $declarations ) {
26902690
* @since 6.1.0
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.
26952696
* @param array $selectors Optional list of selectors per block.
26962697
* @param array $options {
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.
27022704
*/
@@ -2712,57 +2714,82 @@ private static function get_block_nodes( $theme_json, $selectors = array(), $opt
27122714
return $nodes;
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-
}
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+
}
27202731

2721-
$duotone_selector = null;
2722-
if ( isset( $selectors[ $name ]['duotone'] ) ) {
2723-
$duotone_selector = $selectors[ $name ]['duotone'];
2724-
}
2732+
$duotone_selector = null;
2733+
if ( isset( $selectors[ $name ]['duotone'] ) ) {
2734+
$duotone_selector = $selectors[ $name ]['duotone'];
2735+
}
27252736

2726-
$feature_selectors = null;
2727-
if ( isset( $selectors[ $name ]['selectors'] ) ) {
2728-
$feature_selectors = $selectors[ $name ]['selectors'];
2729-
}
2737+
$feature_selectors = null;
2738+
if ( isset( $selectors[ $name ]['selectors'] ) ) {
2739+
$feature_selectors = $selectors[ $name ]['selectors'];
2740+
}
27302741

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-
);
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+
}
27392750
}
2740-
}
27412751

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-
);
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
);
27592778

27602779
// Handle any pseudo selectors for the element.
27612780
if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) {
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
);
27682795
}
@@ -3236,7 +3263,11 @@ public function merge( $incoming ) {
32363263
* some values provide exceptions, namely style values that are
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'];
32423273
/*

tests/phpunit/tests/theme/wpThemeJson.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2443,6 +2443,60 @@ public function test_merge_incoming_background_styles() {
24432443
$this->assertEqualSetsWithIndex( $expected, $actual );
24442444
}
24452445

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 );
2498+
}
2499+
24462500
/**
24472501
* @ticket 54336
24482502
*/

0 commit comments

Comments
 (0)