From 90039c329c7f58593ab0f0717069d63b4ed84a7b Mon Sep 17 00:00:00 2001 From: Md Rashed Hossain Date: Mon, 13 Apr 2026 17:52:24 +0600 Subject: [PATCH 01/11] Update style-rtl.css --- src/wp-content/themes/twentynineteen/style-rtl.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-content/themes/twentynineteen/style-rtl.css b/src/wp-content/themes/twentynineteen/style-rtl.css index d09ae598bf95c..2bb69e0f9258b 100644 --- a/src/wp-content/themes/twentynineteen/style-rtl.css +++ b/src/wp-content/themes/twentynineteen/style-rtl.css @@ -4443,6 +4443,11 @@ body.page .main-navigation { max-width: 100% !important; } +.wp-block-embed__wrapper iframe[src*="youtube.com/shorts"] { + aspect-ratio: 9 / 16; + height: auto; +} + @media only screen and (min-width: 768px) { .entry .entry-content > iframe[style] { max-width: calc(8 * (100vw / 12) - 28px) !important; From a4548d21538397787dca723c29d36093944fb628 Mon Sep 17 00:00:00 2001 From: "wordpress-develop-pr-bot[bot]" <1178653+wordpress-develop-pr-bot[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 11:55:12 +0000 Subject: [PATCH 02/11] Automation: Updating built files with changes. --- src/wp-content/themes/twentynineteen/style-rtl.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/wp-content/themes/twentynineteen/style-rtl.css b/src/wp-content/themes/twentynineteen/style-rtl.css index f0234fcf1d882..ae969d6e88e84 100644 --- a/src/wp-content/themes/twentynineteen/style-rtl.css +++ b/src/wp-content/themes/twentynineteen/style-rtl.css @@ -4445,11 +4445,6 @@ body.page .main-navigation { max-width: 100% !important; } -.wp-block-embed__wrapper iframe[src*="youtube.com/shorts"] { - aspect-ratio: 9 / 16; - height: auto; -} - @media only screen and (min-width: 768px) { .entry .entry-content > iframe[style] { max-width: calc(8 * (100vw / 12) - 28px) !important; From 3496be702da1c0d04eaf9fe47799bc866e1f4718 Mon Sep 17 00:00:00 2001 From: Rashed Hossain Date: Thu, 7 May 2026 17:52:21 +0600 Subject: [PATCH 03/11] Add aspect ratio for YouTube shorts embeds --- src/wp-content/themes/twentynineteen/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-content/themes/twentynineteen/style.css b/src/wp-content/themes/twentynineteen/style.css index 1dafa52fd6be7..ead5c60246f01 100644 --- a/src/wp-content/themes/twentynineteen/style.css +++ b/src/wp-content/themes/twentynineteen/style.css @@ -4120,6 +4120,11 @@ body.page .main-navigation { /* Browsers supporting mix-blend-mode don't need opacity < 1 */ } +.wp-block-embed__wrapper iframe[src*="youtube.com/shorts"] { + aspect-ratio: 9 / 16; + height: auto; +} + @supports (mix-blend-mode: multiply) { .image-filters-enabled .site-header.featured-image .site-featured-image:after { opacity: 1; From c4d9c446794a72b2d594d29a67c6ab6b155979be Mon Sep 17 00:00:00 2001 From: "wordpress-develop-pr-bot[bot]" <1178653+wordpress-develop-pr-bot[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 12:01:29 +0000 Subject: [PATCH 04/11] Automation: Updating built files with changes. --- src/wp-content/themes/twentynineteen/style-rtl.css | 5 +++++ src/wp-content/themes/twentynineteen/style.css | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wp-content/themes/twentynineteen/style-rtl.css b/src/wp-content/themes/twentynineteen/style-rtl.css index ae969d6e88e84..31b74537d8f95 100644 --- a/src/wp-content/themes/twentynineteen/style-rtl.css +++ b/src/wp-content/themes/twentynineteen/style-rtl.css @@ -4114,6 +4114,11 @@ body.page .main-navigation { /* Browsers supporting mix-blend-mode don't need opacity < 1 */ } +.wp-block-embed__wrapper iframe[src*="youtube.com/shorts"] { + aspect-ratio: 9 / 16; + height: auto; +} + @supports (mix-blend-mode: multiply) { .image-filters-enabled .site-header.featured-image .site-featured-image:after { opacity: 1; diff --git a/src/wp-content/themes/twentynineteen/style.css b/src/wp-content/themes/twentynineteen/style.css index ead5c60246f01..1dafa52fd6be7 100644 --- a/src/wp-content/themes/twentynineteen/style.css +++ b/src/wp-content/themes/twentynineteen/style.css @@ -4120,11 +4120,6 @@ body.page .main-navigation { /* Browsers supporting mix-blend-mode don't need opacity < 1 */ } -.wp-block-embed__wrapper iframe[src*="youtube.com/shorts"] { - aspect-ratio: 9 / 16; - height: auto; -} - @supports (mix-blend-mode: multiply) { .image-filters-enabled .site-header.featured-image .site-featured-image:after { opacity: 1; From 20904249ab7fd51378f4603936d7cd381a8bcc69 Mon Sep 17 00:00:00 2001 From: "wordpress-develop-pr-bot[bot]" <1178653+wordpress-develop-pr-bot[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 12:02:35 +0000 Subject: [PATCH 05/11] Automation: Updating built files with changes. --- src/wp-content/themes/twentynineteen/style-rtl.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/wp-content/themes/twentynineteen/style-rtl.css b/src/wp-content/themes/twentynineteen/style-rtl.css index 31b74537d8f95..ae969d6e88e84 100644 --- a/src/wp-content/themes/twentynineteen/style-rtl.css +++ b/src/wp-content/themes/twentynineteen/style-rtl.css @@ -4114,11 +4114,6 @@ body.page .main-navigation { /* Browsers supporting mix-blend-mode don't need opacity < 1 */ } -.wp-block-embed__wrapper iframe[src*="youtube.com/shorts"] { - aspect-ratio: 9 / 16; - height: auto; -} - @supports (mix-blend-mode: multiply) { .image-filters-enabled .site-header.featured-image .site-featured-image:after { opacity: 1; From 76c6e2ef3c0a2b316a38ec867cae23cc043e8482 Mon Sep 17 00:00:00 2001 From: Md Rashed Hossain Date: Mon, 18 May 2026 13:49:55 +0600 Subject: [PATCH 06/11] Add native performance optimization settings Introduce a native Performance settings screen with controls for page caching, asset minification, critical CSS, lazy loading, image optimization, and database cleanup. Add core performance helpers for: - registering and sanitizing optimization settings - anonymous front-end page caching with cache invalidation hooks - front-end HTML and inline CSS/JS minification - critical CSS generation from inline styles - lazy-loading controls through existing media filters - AVIF/WebP output format preference when supported - cache clearing and database cleanup actions Wire the new screen into Settings, load the performance runtime during bootstrap, and add focused PHPUnit coverage for the new helpers. --- src/wp-admin/menu.php | 1 + src/wp-admin/options-performance.php | 143 ++++++++++++ src/wp-includes/default-filters.php | 11 + src/wp-includes/performance.php | 327 +++++++++++++++++++++++++++ src/wp-settings.php | 1 + tests/phpunit/tests/performance.php | 98 ++++++++ 6 files changed, 581 insertions(+) create mode 100644 src/wp-admin/options-performance.php create mode 100644 src/wp-includes/performance.php create mode 100644 tests/phpunit/tests/performance.php diff --git a/src/wp-admin/menu.php b/src/wp-admin/menu.php index dc8c4271e9aad..bafac58d5ec57 100644 --- a/src/wp-admin/menu.php +++ b/src/wp-admin/menu.php @@ -409,6 +409,7 @@ function _add_plugin_file_editor_to_tools() { $submenu['options-general.php'][20] = array( __( 'Reading' ), 'manage_options', 'options-reading.php' ); $submenu['options-general.php'][25] = array( __( 'Discussion' ), 'manage_options', 'options-discussion.php' ); $submenu['options-general.php'][30] = array( __( 'Media' ), 'manage_options', 'options-media.php' ); + $submenu['options-general.php'][35] = array( __( 'Performance' ), 'manage_options', 'options-performance.php' ); $submenu['options-general.php'][40] = array( __( 'Permalinks' ), 'manage_options', 'options-permalink.php' ); $submenu['options-general.php'][45] = array( __( 'Privacy' ), 'manage_privacy_options', 'options-privacy.php' ); diff --git a/src/wp-admin/options-performance.php b/src/wp-admin/options-performance.php new file mode 100644 index 0000000000000..720e104e88054 --- /dev/null +++ b/src/wp-admin/options-performance.php @@ -0,0 +1,143 @@ +query( "DELETE FROM $wpdb->posts WHERE post_type = 'revision'" ); + $deleted += (int) $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam'" ); + $deleted += (int) $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_approved = 'trash'" ); + $deleted += (int) $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_edit_lock' OR meta_key = '_edit_last'" ); + wp_clean_performance_page_cache(); + + /* translators: %d: Number of database rows deleted. */ + add_settings_error( 'performance', 'performance_database_cleaned', sprintf( __( 'Database cleanup complete. %d rows were removed.' ), $deleted ), 'success' ); + } +} + +get_current_screen()->add_help_tab( + array( + 'id' => 'overview', + 'title' => __( 'Overview' ), + 'content' => '

' . __( 'Performance settings provide native controls for front-end caching, asset minification, critical CSS generation, lazy loading, image optimization, and database cleanup.' ) . '

', + ) +); + +require_once ABSPATH . 'wp-admin/admin-header.php'; + +$settings = wp_get_performance_optimization_settings(); + +?> + +
+

+ + + +
+ + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +

+
+ + + +
+ + +
+ + + +
+ +
+ + diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 4b6d9de25fa11..433b753182a0b 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -363,6 +363,7 @@ add_action( 'wp_footer', 'wp_print_footer_scripts', 20 ); add_action( 'template_redirect', 'wp_shortlink_header', 11, 0 ); add_action( 'wp_print_footer_scripts', '_wp_footer_scripts' ); +add_action( 'template_redirect', 'wp_start_performance_page_cache', 0 ); add_action( 'init', '_register_core_block_patterns_and_categories' ); add_action( 'init', 'check_theme_switched', 99 ); add_action( 'init', array( 'WP_Block_Supports', 'init' ), 22 ); @@ -531,6 +532,7 @@ add_action( 'init', 'rest_api_init' ); add_action( 'rest_api_init', 'rest_api_default_filters', 10, 1 ); add_action( 'rest_api_init', 'register_initial_settings', 10 ); +add_action( 'rest_api_init', 'wp_register_performance_optimization_settings', 10 ); add_action( 'rest_api_init', 'create_initial_rest_routes', 99 ); add_action( 'parse_request', 'rest_api_loaded' ); @@ -793,6 +795,15 @@ // Collaboration. add_action( 'admin_init', 'wp_collaboration_inject_setting' ); +// Performance optimization. +add_action( 'admin_init', 'wp_register_performance_optimization_settings' ); +add_action( 'save_post', 'wp_clean_performance_page_cache' ); +add_action( 'deleted_post', 'wp_clean_performance_page_cache' ); +add_action( 'clean_post_cache', 'wp_clean_performance_page_cache' ); +add_action( 'transition_comment_status', 'wp_clean_performance_page_cache' ); +add_filter( 'wp_get_loading_optimization_attributes', 'wp_performance_filter_loading_optimization_attributes', 10, 2 ); +add_filter( 'image_editor_output_format', 'wp_performance_filter_image_editor_output_format' ); + // Add ignoredHookedBlocks metadata attribute to the template and template part post types. add_filter( 'rest_pre_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes' ); add_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' ); diff --git a/src/wp-includes/performance.php b/src/wp-includes/performance.php new file mode 100644 index 0000000000000..6d5846c5a7900 --- /dev/null +++ b/src/wp-includes/performance.php @@ -0,0 +1,327 @@ + false, + 'minify_assets' => false, + 'critical_css' => false, + 'lazy_loading' => true, + 'image_optimization' => false, + 'database_cleanup' => false, + ); +} + +function wp_sanitize_performance_optimization_settings( $settings ) { + $defaults = wp_get_performance_optimization_defaults(); + + if ( ! is_array( $settings ) ) { + $settings = array(); + } + + $sanitized = array(); + foreach ( $defaults as $feature => $default ) { + $sanitized[ $feature ] = isset( $settings[ $feature ] ) ? wp_validate_boolean( $settings[ $feature ] ) : $default; + } + + return $sanitized; +} + +function wp_get_performance_optimization_settings() { + $settings = get_option( 'performance_optimization', array() ); + + return wp_parse_args( + wp_sanitize_performance_optimization_settings( $settings ), + wp_get_performance_optimization_defaults() + ); +} + +function wp_performance_optimization_enabled( $feature ) { + $settings = wp_get_performance_optimization_settings(); + + return ! empty( $settings[ $feature ] ); +} + +function wp_register_performance_optimization_settings() { + register_setting( + 'performance', + 'performance_optimization', + array( + 'type' => 'object', + 'description' => __( 'Native performance optimization settings.' ), + 'sanitize_callback' => 'wp_sanitize_performance_optimization_settings', + 'default' => wp_get_performance_optimization_defaults(), + 'show_in_rest' => array( + 'schema' => array( + 'type' => 'object', + 'additionalProperties' => false, + 'properties' => array( + 'page_cache' => array( + 'type' => 'boolean', + 'description' => __( 'Enable built-in page caching for anonymous front-end requests.' ), + ), + 'minify_assets' => array( + 'type' => 'boolean', + 'description' => __( 'Minify front-end HTML and inline CSS and JavaScript.' ), + ), + 'critical_css' => array( + 'type' => 'boolean', + 'description' => __( 'Generate a small cached critical CSS block from early inline styles.' ), + ), + 'lazy_loading' => array( + 'type' => 'boolean', + 'description' => __( 'Add lazy-loading attributes to eligible images and iframes.' ), + ), + 'image_optimization' => array( + 'type' => 'boolean', + 'description' => __( 'Prefer modern image output formats when supported by the server.' ), + ), + 'database_cleanup' => array( + 'type' => 'boolean', + 'description' => __( 'Show database cleanup tools on the Performance settings screen.' ), + ), + ), + ), + ), + ) + ); +} + +function wp_performance_filter_loading_optimization_attributes( $loading_attrs, $tag_name ) { + if ( wp_performance_optimization_enabled( 'lazy_loading' ) || ( 'img' !== $tag_name && 'iframe' !== $tag_name ) ) { + return $loading_attrs; + } + + if ( isset( $loading_attrs['loading'] ) && 'lazy' === $loading_attrs['loading'] ) { + unset( $loading_attrs['loading'] ); + } + + return $loading_attrs; +} + +function wp_performance_filter_image_editor_output_format( $output_format ) { + if ( ! wp_performance_optimization_enabled( 'image_optimization' ) ) { + return $output_format; + } + + $modern_format = ''; + if ( wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) { + $modern_format = 'image/avif'; + } elseif ( wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { + $modern_format = 'image/webp'; + } + + if ( ! $modern_format ) { + return $output_format; + } + + foreach ( array( 'image/jpeg', 'image/png' ) as $mime_type ) { + $output_format[ $mime_type ] = $modern_format; + } + + return $output_format; +} + +function wp_get_performance_cache_dir( $type = '' ) { + $dir = WP_CONTENT_DIR . '/cache/performance'; + + if ( $type ) { + $dir .= '/' . sanitize_key( $type ); + } + + return $dir; +} + +function wp_delete_performance_cache( $type = '' ) { + $dir = wp_get_performance_cache_dir( $type ); + + if ( ! is_dir( $dir ) ) { + return true; + } + + $items = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS ), + RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ( $items as $item ) { + if ( $item->isDir() ) { + rmdir( $item->getPathname() ); + } else { + unlink( $item->getPathname() ); + } + } + + return rmdir( $dir ); +} + +function wp_clean_performance_page_cache() { + wp_delete_performance_cache( 'page' ); +} + +function wp_can_optimize_performance_output() { + if ( + ( + ! wp_performance_optimization_enabled( 'page_cache' ) && + ! wp_performance_optimization_enabled( 'minify_assets' ) && + ! wp_performance_optimization_enabled( 'critical_css' ) + ) || + is_admin() || + is_user_logged_in() || + wp_doing_ajax() || + wp_is_json_request() || + is_feed() || + is_robots() || + is_trackback() || + ( defined( 'DONOTCACHEPAGE' ) && DONOTCACHEPAGE ) + ) { + return false; + } + + if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'GET' !== $_SERVER['REQUEST_METHOD'] ) { + return false; + } + + if ( ! empty( $_COOKIE[ LOGGED_IN_COOKIE ] ) || ! empty( $_COOKIE['comment_author_' . COOKIEHASH ] ) || ! empty( $_GET['preview'] ) ) { + return false; + } + + return (bool) apply_filters( 'wp_can_optimize_performance_output', true ); +} + +function wp_can_use_performance_page_cache() { + if ( ! wp_performance_optimization_enabled( 'page_cache' ) || ! wp_can_optimize_performance_output() ) { + return false; + } + + return (bool) apply_filters( 'wp_can_use_performance_page_cache', true ); +} + +function wp_get_performance_page_cache_file() { + $url = home_url( add_query_arg( null, null ) ); + + return wp_get_performance_cache_dir( 'page' ) . '/' . md5( $url ) . '.html'; +} + +function wp_start_performance_page_cache() { + if ( ! wp_can_optimize_performance_output() ) { + return; + } + + $cache_file = wp_get_performance_page_cache_file(); + $ttl = (int) apply_filters( 'wp_performance_page_cache_ttl', HOUR_IN_SECONDS ); + + if ( wp_can_use_performance_page_cache() && is_readable( $cache_file ) && filemtime( $cache_file ) > time() - $ttl ) { + header( 'X-WP-Performance-Cache: HIT' ); + readfile( $cache_file ); + exit; + } + + if ( wp_performance_optimization_enabled( 'page_cache' ) ) { + header( 'X-WP-Performance-Cache: MISS' ); + } + + ob_start( 'wp_capture_performance_page_cache' ); +} + +function wp_capture_performance_page_cache( $output ) { + if ( ! wp_can_optimize_performance_output() || 200 !== http_response_code() || false === stripos( $output, ']*>(.*?)#is', $html, $matches ) ) { + return $html; + } + + $critical_css = ''; + foreach ( $matches[1] as $css ) { + $critical_css .= "\n" . trim( wp_minify_performance_css( $css ) ); + if ( strlen( $critical_css ) >= 12000 ) { + break; + } + } + + if ( '' === trim( $critical_css ) ) { + return $html; + } + + $style = ''; + + return preg_replace( '##i', $style . '', $html, 1 ); +} + +function wp_minify_performance_output( $html ) { + $html = preg_replace_callback( + '#]*)>(.*?)#is', + static function ( $matches ) { + return '' . wp_minify_performance_css( $matches[2] ) . ''; + }, + $html + ); + + $html = preg_replace_callback( + '#]*)>(.*?)#is', + static function ( $matches ) { + if ( preg_match( '/\btype=(["\'])(?!text\/javascript|application\/javascript|module)/i', $matches[1] ) ) { + return $matches[0]; + } + + return '' . wp_minify_performance_js( $matches[2] ) . ''; + }, + $html + ); + + $html = preg_replace( '//s', '', $html ); + $html = preg_replace( '/>\s+<', $html ); + + return trim( $html ); +} + +function wp_minify_performance_css( $css ) { + $css = preg_replace( '#/\*.*?\*/#s', '', $css ); + $css = preg_replace( '/\s+/', ' ', $css ); + $css = preg_replace( '/\s*([{}:;,>])\s*/', '$1', $css ); + + return trim( $css ); +} + +function wp_minify_performance_js( $js ) { + $js = preg_replace( '#/\*.*?\*/#s', '', $js ); + $js = preg_replace( '/\s+/', ' ', $js ); + + return trim( $js ); +} diff --git a/src/wp-settings.php b/src/wp-settings.php index dab1d8fd4c0de..433cd16ebdb64 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -261,6 +261,7 @@ require ABSPATH . WPINC . '/class-wp-oembed.php'; require ABSPATH . WPINC . '/class-wp-oembed-controller.php'; require ABSPATH . WPINC . '/media.php'; +require ABSPATH . WPINC . '/performance.php'; require ABSPATH . WPINC . '/http.php'; require ABSPATH . WPINC . '/html-api/html5-named-character-references.php'; require ABSPATH . WPINC . '/html-api/class-wp-html-attribute-token.php'; diff --git a/tests/phpunit/tests/performance.php b/tests/phpunit/tests/performance.php new file mode 100644 index 0000000000000..0ff1fae10f850 --- /dev/null +++ b/tests/phpunit/tests/performance.php @@ -0,0 +1,98 @@ + '1', + 'lazy_loading' => '0', + 'unknown_value' => true, + ) + ); + + $this->assertTrue( $settings['page_cache'] ); + $this->assertFalse( $settings['lazy_loading'] ); + $this->assertFalse( $settings['minify_assets'] ); + $this->assertArrayNotHasKey( 'unknown_value', $settings ); + } + + /** + * Tests disabling lazy loading removes only lazy loading attributes. + */ + public function test_wp_performance_filter_loading_optimization_attributes_removes_lazy_loading_when_disabled() { + update_option( + 'performance_optimization', + array( + 'lazy_loading' => false, + ) + ); + + $attributes = wp_performance_filter_loading_optimization_attributes( + array( + 'loading' => 'lazy', + 'fetchpriority' => 'high', + ), + 'img' + ); + + $this->assertArrayNotHasKey( 'loading', $attributes ); + $this->assertSame( 'high', $attributes['fetchpriority'] ); + } + + /** + * Tests image output mappings are unchanged while image optimization is disabled. + */ + public function test_wp_performance_filter_image_editor_output_format_returns_existing_map_when_disabled() { + $output_format = array( + 'image/heic' => 'image/jpeg', + ); + + $this->assertSame( $output_format, wp_performance_filter_image_editor_output_format( $output_format ) ); + } + + /** + * Tests critical CSS generation from inline styles. + */ + public function test_wp_add_performance_critical_css_adds_inline_block() { + $html = ''; + + $this->assertStringContainsString( + '', + wp_add_performance_critical_css( $html ) + ); + } + + /** + * Tests output minification. + */ + public function test_wp_minify_performance_output_minifies_inline_css_and_html() { + $html = "\n\n

Test

\n"; + + $this->assertSame( + '

Test

', + wp_minify_performance_output( $html ) + ); + } +} From b15ef2825158e2cf727229a3ad5f76aacef9dee7 Mon Sep 17 00:00:00 2001 From: Md Rashed Hossain Date: Mon, 18 May 2026 13:56:14 +0600 Subject: [PATCH 07/11] fixed the conflict --- src/wp-admin/includes/admin-filters.php | 1 + src/wp-includes/default-filters.php | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/admin-filters.php b/src/wp-admin/includes/admin-filters.php index 5337cc02c88c9..95868afdb85a9 100644 --- a/src/wp-admin/includes/admin-filters.php +++ b/src/wp-admin/includes/admin-filters.php @@ -45,6 +45,7 @@ // Misc hooks. add_action( 'admin_init', 'wp_admin_headers' ); add_action( 'admin_init', 'send_frame_options_header', 10, 0 ); +add_action( 'admin_init', 'wp_register_performance_optimization_settings' ); add_action( 'admin_head', 'wp_admin_canonical_url' ); add_action( 'admin_head', 'wp_site_icon' ); add_action( 'admin_head', 'wp_admin_viewport_meta' ); diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 433b753182a0b..0926ac76c8579 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -796,7 +796,6 @@ add_action( 'admin_init', 'wp_collaboration_inject_setting' ); // Performance optimization. -add_action( 'admin_init', 'wp_register_performance_optimization_settings' ); add_action( 'save_post', 'wp_clean_performance_page_cache' ); add_action( 'deleted_post', 'wp_clean_performance_page_cache' ); add_action( 'clean_post_cache', 'wp_clean_performance_page_cache' ); From 66532b7b9190a27d298382f4f514e62c57954c25 Mon Sep 17 00:00:00 2001 From: Md Rashed Hossain Date: Mon, 18 May 2026 14:12:10 +0600 Subject: [PATCH 08/11] fixed coding standard issues --- src/wp-admin/includes/admin-filters.php | 2 +- src/wp-admin/options-performance.php | 2 ++ src/wp-includes/performance.php | 23 ++++++++++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/wp-admin/includes/admin-filters.php b/src/wp-admin/includes/admin-filters.php index 95868afdb85a9..78bad24c1571f 100644 --- a/src/wp-admin/includes/admin-filters.php +++ b/src/wp-admin/includes/admin-filters.php @@ -45,7 +45,7 @@ // Misc hooks. add_action( 'admin_init', 'wp_admin_headers' ); add_action( 'admin_init', 'send_frame_options_header', 10, 0 ); -add_action( 'admin_init', 'wp_register_performance_optimization_settings' ); +add_action( 'admin_init', 'wp_maybe_register_performance_optimization_settings' ); add_action( 'admin_head', 'wp_admin_canonical_url' ); add_action( 'admin_head', 'wp_site_icon' ); add_action( 'admin_head', 'wp_admin_viewport_meta' ); diff --git a/src/wp-admin/options-performance.php b/src/wp-admin/options-performance.php index 720e104e88054..c47d18eaa1c30 100644 --- a/src/wp-admin/options-performance.php +++ b/src/wp-admin/options-performance.php @@ -18,6 +18,8 @@ $title = __( 'Performance Settings' ); $parent_file = 'options-general.php'; +wp_register_performance_optimization_settings(); + if ( isset( $_POST['performance_action'] ) ) { check_admin_referer( 'performance-tools' ); diff --git a/src/wp-includes/performance.php b/src/wp-includes/performance.php index 6d5846c5a7900..46011ffd6c322 100644 --- a/src/wp-includes/performance.php +++ b/src/wp-includes/performance.php @@ -47,6 +47,12 @@ function wp_performance_optimization_enabled( $feature ) { } function wp_register_performance_optimization_settings() { + global $wp_registered_settings; + + if ( isset( $wp_registered_settings['performance_optimization'] ) ) { + return; + } + register_setting( 'performance', 'performance_optimization', @@ -91,6 +97,17 @@ function wp_register_performance_optimization_settings() { ); } +function wp_maybe_register_performance_optimization_settings() { + global $pagenow; + + $is_performance_screen = 'options-performance.php' === $pagenow; + $is_options_screen = 'options.php' === $pagenow; + + if ( $is_performance_screen || $is_options_screen ) { + wp_register_performance_optimization_settings(); + } +} + function wp_performance_filter_loading_optimization_attributes( $loading_attrs, $tag_name ) { if ( wp_performance_optimization_enabled( 'lazy_loading' ) || ( 'img' !== $tag_name && 'iframe' !== $tag_name ) ) { return $loading_attrs; @@ -186,7 +203,11 @@ function wp_can_optimize_performance_output() { return false; } - if ( ! empty( $_COOKIE[ LOGGED_IN_COOKIE ] ) || ! empty( $_COOKIE['comment_author_' . COOKIEHASH ] ) || ! empty( $_GET['preview'] ) ) { + $has_logged_in_cookie = ! empty( $_COOKIE[LOGGED_IN_COOKIE] ); + $has_comment_author_cookie = ! empty( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ); + $has_preview = ! empty( $_GET['preview'] ); + + if ( $has_logged_in_cookie || $has_comment_author_cookie || $has_preview ) { return false; } From 9fa6cdc82d88ad4c89373a5fa75db47d684c403c Mon Sep 17 00:00:00 2001 From: Md Rashed Hossain Date: Mon, 18 May 2026 15:00:11 +0600 Subject: [PATCH 09/11] Update performance.php --- src/wp-includes/performance.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/performance.php b/src/wp-includes/performance.php index 46011ffd6c322..588b83f45e9a9 100644 --- a/src/wp-includes/performance.php +++ b/src/wp-includes/performance.php @@ -203,9 +203,9 @@ function wp_can_optimize_performance_output() { return false; } - $has_logged_in_cookie = ! empty( $_COOKIE[LOGGED_IN_COOKIE] ); + $has_logged_in_cookie = ! empty( $_COOKIE[ LOGGED_IN_COOKIE ] ); $has_comment_author_cookie = ! empty( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ); - $has_preview = ! empty( $_GET['preview'] ); + $has_preview = ! empty( $_GET['preview'] ); if ( $has_logged_in_cookie || $has_comment_author_cookie || $has_preview ) { return false; @@ -290,7 +290,7 @@ function wp_add_performance_critical_css( $html ) { $critical_css = ''; foreach ( $matches[1] as $css ) { - $critical_css .= "\n" . trim( wp_minify_performance_css( $css ) ); + $critical_css .= trim( wp_minify_performance_css( $css ) ); if ( strlen( $critical_css ) >= 12000 ) { break; } From babd79f0111f121c962a55b9e185671ef01bb61c Mon Sep 17 00:00:00 2001 From: Md Rashed Hossain Date: Mon, 18 May 2026 15:00:31 +0600 Subject: [PATCH 10/11] Update performance.php --- src/wp-includes/performance.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp-includes/performance.php b/src/wp-includes/performance.php index 588b83f45e9a9..05c819e2c7a75 100644 --- a/src/wp-includes/performance.php +++ b/src/wp-includes/performance.php @@ -100,6 +100,10 @@ function wp_register_performance_optimization_settings() { function wp_maybe_register_performance_optimization_settings() { global $pagenow; + if ( wp_doing_ajax() ) { + return; + } + $is_performance_screen = 'options-performance.php' === $pagenow; $is_options_screen = 'options.php' === $pagenow; From cff3e44efd89778c985371609dccb486d54ad3ea Mon Sep 17 00:00:00 2001 From: Rashed Hossain Date: Tue, 26 May 2026 12:19:56 +0600 Subject: [PATCH 11/11] Editor: Warn in Classic Editor when serialized block comments are present Add a Classic Editor warning for posts/pages whose content contains WordPress block comment syntax (). This helps prevent accidental overwrites when the Visual tab appears empty but block markup still exists in the Code tab. The notice is: Scoped to the Classic Editor content field (#content). Shown only when block comment markup is detected. Inserted inline above the editor (#wp-content-wrap). Guarded against duplicate rendering. --- src/js/_enqueues/admin/post.js | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/js/_enqueues/admin/post.js b/src/js/_enqueues/admin/post.js index d50fe6007d33b..9a5bbd7309acd 100644 --- a/src/js/_enqueues/admin/post.js +++ b/src/js/_enqueues/admin/post.js @@ -316,7 +316,46 @@ jQuery( function($) { copyAttachmentURLSuccessTimeout, __ = wp.i18n.__, _x = wp.i18n._x; + /** + * Show a warning in the classic editor when the post content includes + * serialized block comments, which may not be visible in the Visual tab. + */ + function maybeShowBlockMarkupWarning() { + var hasBlockMarkup, $warning, $editorWrapper; + + if ( ! $textarea.length ) { + return; + } + + hasBlockMarkup = //.test( $textarea.val() ); + if ( ! hasBlockMarkup ) { + return; + } + + $warning = $( '#classic-editor-block-markup-notice' ); + if ( $warning.length ) { + return; + } + + $warning = $( '
', { + id: 'classic-editor-block-markup-notice', + 'class': 'notice notice-warning inline' + } ).append( + $( '

' ).text( + __( + 'This content includes Gutenberg block markup that may be visible in the Code editor but not in the Visual editor. The page may not be empty. Review the content carefully before overwriting or deleting it.' + ) + ) + ); + + $editorWrapper = $( '#wp-content-wrap' ); + if ( $editorWrapper.length ) { + $editorWrapper.before( $warning ); + } + } + postboxes.add_postbox_toggles(pagenow); + maybeShowBlockMarkupWarning(); /* * Clear the window name. Otherwise if this is a former preview window where the user navigated to edit another post,