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 https://github.com/WordPress/wordpress-develop/pull/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: http://core.svn.wordpress.org/trunk@60266 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
@@ -492,6 +492,14 @@ class WP_Block {
|
||||
public function render( $options = array() ) {
|
||||
global $post;
|
||||
|
||||
// Capture the current assets queues and then clear out to capture the diff of what was introduced by rendering.
|
||||
$before_styles_queue = wp_styles()->queue;
|
||||
$before_scripts_queue = wp_scripts()->queue;
|
||||
$before_script_modules_queue = wp_script_modules()->queue;
|
||||
wp_styles()->queue = array();
|
||||
wp_scripts()->queue = array();
|
||||
wp_script_modules()->queue = array();
|
||||
|
||||
/*
|
||||
* There can be only one root interactive block at a time because the rendered HTML of that block contains
|
||||
* the rendered HTML of all its inner blocks, including any interactive block.
|
||||
@@ -661,6 +669,44 @@ class WP_Block {
|
||||
$root_interactive_block = null;
|
||||
}
|
||||
|
||||
// Capture the new assets enqueued during rendering, and restore the queues the state prior to rendering.
|
||||
$new_styles_queue = wp_styles()->queue;
|
||||
$new_scripts_queue = wp_scripts()->queue;
|
||||
$new_script_modules_queue = wp_script_modules()->queue;
|
||||
wp_styles()->queue = $before_styles_queue;
|
||||
wp_scripts()->queue = $before_scripts_queue;
|
||||
wp_script_modules()->queue = $before_script_modules_queue;
|
||||
$has_new_styles = count( $new_styles_queue ) > 0;
|
||||
$has_new_scripts = count( $new_scripts_queue ) > 0;
|
||||
$has_new_script_modules = count( $new_script_modules_queue ) > 0;
|
||||
|
||||
// Merge the newly enqueued assets with the existing assets if the rendered block is not empty.
|
||||
if (
|
||||
( $has_new_styles || $has_new_scripts || $has_new_script_modules ) &&
|
||||
(
|
||||
trim( $block_content ) !== '' ||
|
||||
/**
|
||||
* Filters whether to enqueue assets for a block which has no rendered content.
|
||||
*
|
||||
* @since 6.9.0
|
||||
*
|
||||
* @param bool $enqueue Whether to enqueue assets.
|
||||
* @param string $block_name Block name.
|
||||
*/
|
||||
(bool) apply_filters( 'enqueue_empty_block_content_assets', false, $this->name )
|
||||
)
|
||||
) {
|
||||
if ( $has_new_styles ) {
|
||||
wp_styles()->queue = array_unique( array_merge( wp_styles()->queue, $new_styles_queue ) );
|
||||
}
|
||||
if ( $has_new_scripts ) {
|
||||
wp_scripts()->queue = array_unique( array_merge( wp_scripts()->queue, $new_scripts_queue ) );
|
||||
}
|
||||
if ( $has_new_script_modules ) {
|
||||
wp_script_modules()->queue = array_unique( array_merge( wp_script_modules()->queue, $new_script_modules_queue ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $block_content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ class WP_Script_Modules {
|
||||
private $registered = array();
|
||||
|
||||
/**
|
||||
* Holds the script module identifiers that were enqueued before registered.
|
||||
* An array of IDs for queued script modules.
|
||||
*
|
||||
* @since 6.5.0
|
||||
* @var array<string, true>
|
||||
* @since 6.9.0
|
||||
* @var string[]
|
||||
*/
|
||||
private $enqueued_before_registered = array();
|
||||
public $queue = array();
|
||||
|
||||
/**
|
||||
* Tracks whether the @wordpress/a11y script module is available.
|
||||
@@ -122,7 +122,6 @@ class WP_Script_Modules {
|
||||
$this->registered[ $id ] = array(
|
||||
'src' => $src,
|
||||
'version' => $version,
|
||||
'enqueue' => isset( $this->enqueued_before_registered[ $id ] ),
|
||||
'dependencies' => $dependencies,
|
||||
'fetchpriority' => $fetchpriority,
|
||||
);
|
||||
@@ -213,13 +212,11 @@ class WP_Script_Modules {
|
||||
* }
|
||||
*/
|
||||
public function enqueue( string $id, string $src = '', array $deps = array(), $version = false, array $args = array() ) {
|
||||
if ( isset( $this->registered[ $id ] ) ) {
|
||||
$this->registered[ $id ]['enqueue'] = true;
|
||||
} elseif ( $src ) {
|
||||
if ( ! in_array( $id, $this->queue, true ) ) {
|
||||
$this->queue[] = $id;
|
||||
}
|
||||
if ( ! isset( $this->registered[ $id ] ) && $src ) {
|
||||
$this->register( $id, $src, $deps, $version, $args );
|
||||
$this->registered[ $id ]['enqueue'] = true;
|
||||
} else {
|
||||
$this->enqueued_before_registered[ $id ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,10 +228,7 @@ class WP_Script_Modules {
|
||||
* @param string $id The identifier of the script module.
|
||||
*/
|
||||
public function dequeue( string $id ) {
|
||||
if ( isset( $this->registered[ $id ] ) ) {
|
||||
$this->registered[ $id ]['enqueue'] = false;
|
||||
}
|
||||
unset( $this->enqueued_before_registered[ $id ] );
|
||||
$this->queue = array_diff( $this->queue, array( $id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,8 +239,8 @@ class WP_Script_Modules {
|
||||
* @param string $id The identifier of the script module.
|
||||
*/
|
||||
public function deregister( string $id ) {
|
||||
$this->dequeue( $id );
|
||||
unset( $this->registered[ $id ] );
|
||||
unset( $this->enqueued_before_registered[ $id ] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -304,9 +298,9 @@ class WP_Script_Modules {
|
||||
* @since 6.5.0
|
||||
*/
|
||||
public function print_script_module_preloads() {
|
||||
foreach ( $this->get_dependencies( array_keys( $this->get_marked_for_enqueue() ), array( 'static' ) ) as $id => $script_module ) {
|
||||
foreach ( $this->get_dependencies( array_unique( $this->queue ), array( 'static' ) ) as $id => $script_module ) {
|
||||
// Don't preload if it's marked for enqueue.
|
||||
if ( true !== $script_module['enqueue'] ) {
|
||||
if ( ! in_array( $id, $this->queue, true ) ) {
|
||||
echo sprintf(
|
||||
'<link rel="modulepreload" href="%s" id="%s"%s>',
|
||||
esc_url( $this->get_src( $id ) ),
|
||||
@@ -345,7 +339,7 @@ class WP_Script_Modules {
|
||||
*/
|
||||
private function get_import_map(): array {
|
||||
$imports = array();
|
||||
foreach ( $this->get_dependencies( array_keys( $this->get_marked_for_enqueue() ) ) as $id => $script_module ) {
|
||||
foreach ( $this->get_dependencies( array_unique( $this->queue ) ) as $id => $script_module ) {
|
||||
$imports[ $id ] = $this->get_src( $id );
|
||||
}
|
||||
return array( 'imports' => $imports );
|
||||
@@ -359,13 +353,10 @@ class WP_Script_Modules {
|
||||
* @return array<string, array> Script modules marked for enqueue, keyed by script module identifier.
|
||||
*/
|
||||
private function get_marked_for_enqueue(): array {
|
||||
$enqueued = array();
|
||||
foreach ( $this->registered as $id => $script_module ) {
|
||||
if ( true === $script_module['enqueue'] ) {
|
||||
$enqueued[ $id ] = $script_module;
|
||||
}
|
||||
}
|
||||
return $enqueued;
|
||||
return wp_array_slice_assoc(
|
||||
$this->registered,
|
||||
$this->queue
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -457,7 +448,7 @@ class WP_Script_Modules {
|
||||
*/
|
||||
public function print_script_module_data(): void {
|
||||
$modules = array();
|
||||
foreach ( array_keys( $this->get_marked_for_enqueue() ) as $id ) {
|
||||
foreach ( array_unique( $this->queue ) as $id ) {
|
||||
if ( '@wordpress/a11y' === $id ) {
|
||||
$this->a11y_available = true;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '6.9-alpha-60929';
|
||||
$wp_version = '6.9-alpha-60930';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
||||
Reference in New Issue
Block a user