Skip to content

Commit 8645f0f

Browse files
committed
Editor: Avoid enqueueing assets for blocks which do not render content.
This change prevents scripts, styles, and script modules from being enqueued for blocks that do not render any HTML content. This is common for hidden blocks or blocks like the Featured Image block when no image is present. This change reduces the amount of unused CSS and JavaScript on a page, improving performance. A new filter, `enqueue_empty_block_content_assets`, is introduced to allow developers to override this behavior and enqueue assets for empty blocks if needed. The implementation involves capturing the asset queues before and after a block is rendered. The newly enqueued assets are only merged if the block's rendered content is not empty. This is done recursively for nested blocks to ensure that assets for inner blocks are also not enqueued if a parent block is hidden. Developed in WordPress/wordpress-develop#9213. Props westonruter, aristath, peterwilsoncc, gziolo, krupajnanda, dd32, jorbin. See #50328. Fixes #63676. Built from https://develop.svn.wordpress.org/trunk@60930 git-svn-id: https://core.svn.wordpress.org/trunk@60266 1a063a9b-81f0-0310-95a4-ce76da25c4cd
1 parent b814144 commit 8645f0f

File tree

3 files changed

+65
-28
lines changed

3 files changed

+65
-28
lines changed

wp-includes/class-wp-block.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,14 @@ public function replace_rich_text( $rich_text ) {
492492
public function render( $options = array() ) {
493493
global $post;
494494

495+
// Capture the current assets queues and then clear out to capture the diff of what was introduced by rendering.
496+
$before_styles_queue = wp_styles()->queue;
497+
$before_scripts_queue = wp_scripts()->queue;
498+
$before_script_modules_queue = wp_script_modules()->queue;
499+
wp_styles()->queue = array();
500+
wp_scripts()->queue = array();
501+
wp_script_modules()->queue = array();
502+
495503
/*
496504
* There can be only one root interactive block at a time because the rendered HTML of that block contains
497505
* the rendered HTML of all its inner blocks, including any interactive block.
@@ -661,6 +669,44 @@ public function render( $options = array() ) {
661669
$root_interactive_block = null;
662670
}
663671

672+
// Capture the new assets enqueued during rendering, and restore the queues the state prior to rendering.
673+
$new_styles_queue = wp_styles()->queue;
674+
$new_scripts_queue = wp_scripts()->queue;
675+
$new_script_modules_queue = wp_script_modules()->queue;
676+
wp_styles()->queue = $before_styles_queue;
677+
wp_scripts()->queue = $before_scripts_queue;
678+
wp_script_modules()->queue = $before_script_modules_queue;
679+
$has_new_styles = count( $new_styles_queue ) > 0;
680+
$has_new_scripts = count( $new_scripts_queue ) > 0;
681+
$has_new_script_modules = count( $new_script_modules_queue ) > 0;
682+
683+
// Merge the newly enqueued assets with the existing assets if the rendered block is not empty.
684+
if (
685+
( $has_new_styles || $has_new_scripts || $has_new_script_modules ) &&
686+
(
687+
trim( $block_content ) !== '' ||
688+
/**
689+
* Filters whether to enqueue assets for a block which has no rendered content.
690+
*
691+
* @since 6.9.0
692+
*
693+
* @param bool $enqueue Whether to enqueue assets.
694+
* @param string $block_name Block name.
695+
*/
696+
(bool) apply_filters( 'enqueue_empty_block_content_assets', false, $this->name )
697+
)
698+
) {
699+
if ( $has_new_styles ) {
700+
wp_styles()->queue = array_unique( array_merge( wp_styles()->queue, $new_styles_queue ) );
701+
}
702+
if ( $has_new_scripts ) {
703+
wp_scripts()->queue = array_unique( array_merge( wp_scripts()->queue, $new_scripts_queue ) );
704+
}
705+
if ( $has_new_script_modules ) {
706+
wp_script_modules()->queue = array_unique( array_merge( wp_script_modules()->queue, $new_script_modules_queue ) );
707+
}
708+
}
709+
664710
return $block_content;
665711
}
666712
}

wp-includes/class-wp-script-modules.php

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ class WP_Script_Modules {
2323
private $registered = array();
2424

2525
/**
26-
* Holds the script module identifiers that were enqueued before registered.
26+
* An array of IDs for queued script modules.
2727
*
28-
* @since 6.5.0
29-
* @var array<string, true>
28+
* @since 6.9.0
29+
* @var string[]
3030
*/
31-
private $enqueued_before_registered = array();
31+
public $queue = array();
3232

3333
/**
3434
* Tracks whether the @wordpress/a11y script module is available.
@@ -122,7 +122,6 @@ public function register( string $id, string $src, array $deps = array(), $versi
122122
$this->registered[ $id ] = array(
123123
'src' => $src,
124124
'version' => $version,
125-
'enqueue' => isset( $this->enqueued_before_registered[ $id ] ),
126125
'dependencies' => $dependencies,
127126
'fetchpriority' => $fetchpriority,
128127
);
@@ -213,13 +212,11 @@ public function set_fetchpriority( string $id, string $priority ): bool {
213212
* }
214213
*/
215214
public function enqueue( string $id, string $src = '', array $deps = array(), $version = false, array $args = array() ) {
216-
if ( isset( $this->registered[ $id ] ) ) {
217-
$this->registered[ $id ]['enqueue'] = true;
218-
} elseif ( $src ) {
215+
if ( ! in_array( $id, $this->queue, true ) ) {
216+
$this->queue[] = $id;
217+
}
218+
if ( ! isset( $this->registered[ $id ] ) && $src ) {
219219
$this->register( $id, $src, $deps, $version, $args );
220-
$this->registered[ $id ]['enqueue'] = true;
221-
} else {
222-
$this->enqueued_before_registered[ $id ] = true;
223220
}
224221
}
225222

@@ -231,10 +228,7 @@ public function enqueue( string $id, string $src = '', array $deps = array(), $v
231228
* @param string $id The identifier of the script module.
232229
*/
233230
public function dequeue( string $id ) {
234-
if ( isset( $this->registered[ $id ] ) ) {
235-
$this->registered[ $id ]['enqueue'] = false;
236-
}
237-
unset( $this->enqueued_before_registered[ $id ] );
231+
$this->queue = array_diff( $this->queue, array( $id ) );
238232
}
239233

240234
/**
@@ -245,8 +239,8 @@ public function dequeue( string $id ) {
245239
* @param string $id The identifier of the script module.
246240
*/
247241
public function deregister( string $id ) {
242+
$this->dequeue( $id );
248243
unset( $this->registered[ $id ] );
249-
unset( $this->enqueued_before_registered[ $id ] );
250244
}
251245

252246
/**
@@ -304,9 +298,9 @@ public function print_enqueued_script_modules() {
304298
* @since 6.5.0
305299
*/
306300
public function print_script_module_preloads() {
307-
foreach ( $this->get_dependencies( array_keys( $this->get_marked_for_enqueue() ), array( 'static' ) ) as $id => $script_module ) {
301+
foreach ( $this->get_dependencies( array_unique( $this->queue ), array( 'static' ) ) as $id => $script_module ) {
308302
// Don't preload if it's marked for enqueue.
309-
if ( true !== $script_module['enqueue'] ) {
303+
if ( ! in_array( $id, $this->queue, true ) ) {
310304
echo sprintf(
311305
'<link rel="modulepreload" href="%s" id="%s"%s>',
312306
esc_url( $this->get_src( $id ) ),
@@ -345,7 +339,7 @@ public function print_import_map() {
345339
*/
346340
private function get_import_map(): array {
347341
$imports = array();
348-
foreach ( $this->get_dependencies( array_keys( $this->get_marked_for_enqueue() ) ) as $id => $script_module ) {
342+
foreach ( $this->get_dependencies( array_unique( $this->queue ) ) as $id => $script_module ) {
349343
$imports[ $id ] = $this->get_src( $id );
350344
}
351345
return array( 'imports' => $imports );
@@ -359,13 +353,10 @@ private function get_import_map(): array {
359353
* @return array<string, array> Script modules marked for enqueue, keyed by script module identifier.
360354
*/
361355
private function get_marked_for_enqueue(): array {
362-
$enqueued = array();
363-
foreach ( $this->registered as $id => $script_module ) {
364-
if ( true === $script_module['enqueue'] ) {
365-
$enqueued[ $id ] = $script_module;
366-
}
367-
}
368-
return $enqueued;
356+
return wp_array_slice_assoc(
357+
$this->registered,
358+
$this->queue
359+
);
369360
}
370361

371362
/**
@@ -457,7 +448,7 @@ private function get_src( string $id ): string {
457448
*/
458449
public function print_script_module_data(): void {
459450
$modules = array();
460-
foreach ( array_keys( $this->get_marked_for_enqueue() ) as $id ) {
451+
foreach ( array_unique( $this->queue ) as $id ) {
461452
if ( '@wordpress/a11y' === $id ) {
462453
$this->a11y_available = true;
463454
}

wp-includes/version.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
* @global string $wp_version
1818
*/
19-
$wp_version = '6.9-alpha-60929';
19+
$wp_version = '6.9-alpha-60930';
2020

2121
/**
2222
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.

0 commit comments

Comments
 (0)