From 8dee6b0db1a32af315b2c3281851560394bf9079 Mon Sep 17 00:00:00 2001 From: Dhruvang Shah <105810308+dhruvang21@users.noreply.github.com> Date: Tue, 4 Nov 2025 18:54:57 +0530 Subject: [PATCH 1/5] Embed Optimizer: Switch cross-origin embeds from preconnect to dns-prefetch --- .../class-embed-optimizer-tag-visitor.php | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php b/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php index f338df5dce..e8fe433e4f 100644 --- a/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php +++ b/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php @@ -288,6 +288,27 @@ private function add_preconnect_links( OD_Tag_Visitor_Context $context ): void { $embed_wrapper_xpath = self::get_embed_wrapper_xpath( $processor->get_xpath() ); foreach ( $this->get_preconnect_urls( $processor ) as $preconnect_url ) { + $host = wp_parse_url( $preconnect_url, PHP_URL_HOST ); + + // Skip if malformed URL. + if ( empty( $host ) ) { + continue; + } + + // Determine if same-origin. + $is_same_origin = wp_parse_url( home_url(), PHP_URL_HOST ) === $host; + + /** + * Filter whether preconnect should be used for a given embed host. + * + * Allows developers to override behavior. + * + * @param bool $use_preconnect Whether to use preconnect (default true for same-origin). + * @param string $preconnect_url The URL being hinted. + * @param string $host The parsed host. + */ + $use_preconnect = apply_filters( 'embed_optimizer_use_preconnect', $is_same_origin, $preconnect_url, $host ); + foreach ( $context->url_metric_group_collection as $group ) { if ( $group->get_element_max_intersection_ratio( $embed_wrapper_xpath ) < PHP_FLOAT_EPSILON ) { continue; @@ -295,7 +316,7 @@ private function add_preconnect_links( OD_Tag_Visitor_Context $context ): void { $context->link_collection->add_link( array( - 'rel' => 'preconnect', + 'rel' => $use_preconnect ? 'preconnect' : 'dns-prefetch', 'href' => $preconnect_url, ), $group->get_minimum_viewport_width(), From e059dd370cf676729e2d1f58e71e1d5890fbc497 Mon Sep 17 00:00:00 2001 From: dhruvang21 Date: Wed, 5 Nov 2025 12:18:01 +0530 Subject: [PATCH 2/5] refactor: code suggestion --- .../class-embed-optimizer-tag-visitor.php | 27 +++---------------- 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php b/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php index e8fe433e4f..4558031ff9 100644 --- a/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php +++ b/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php @@ -287,28 +287,7 @@ private function add_preconnect_links( OD_Tag_Visitor_Context $context ): void { $processor = $context->processor; $embed_wrapper_xpath = self::get_embed_wrapper_xpath( $processor->get_xpath() ); - foreach ( $this->get_preconnect_urls( $processor ) as $preconnect_url ) { - $host = wp_parse_url( $preconnect_url, PHP_URL_HOST ); - - // Skip if malformed URL. - if ( empty( $host ) ) { - continue; - } - - // Determine if same-origin. - $is_same_origin = wp_parse_url( home_url(), PHP_URL_HOST ) === $host; - - /** - * Filter whether preconnect should be used for a given embed host. - * - * Allows developers to override behavior. - * - * @param bool $use_preconnect Whether to use preconnect (default true for same-origin). - * @param string $preconnect_url The URL being hinted. - * @param string $host The parsed host. - */ - $use_preconnect = apply_filters( 'embed_optimizer_use_preconnect', $is_same_origin, $preconnect_url, $host ); - + foreach ( $this->get_dns_prefetch_urls( $processor ) as $dns_prefetch_url ) { foreach ( $context->url_metric_group_collection as $group ) { if ( $group->get_element_max_intersection_ratio( $embed_wrapper_xpath ) < PHP_FLOAT_EPSILON ) { continue; @@ -316,8 +295,8 @@ private function add_preconnect_links( OD_Tag_Visitor_Context $context ): void { $context->link_collection->add_link( array( - 'rel' => $use_preconnect ? 'preconnect' : 'dns-prefetch', - 'href' => $preconnect_url, + 'rel' => 'dns-prefetch', + 'href' => $dns_prefetch_url, ), $group->get_minimum_viewport_width(), $group->get_maximum_viewport_width() From a7ae4ea437148b7bc18c52f6ba086a42c0151255 Mon Sep 17 00:00:00 2001 From: dhruvang21 Date: Wed, 5 Nov 2025 12:58:35 +0530 Subject: [PATCH 3/5] fix: phpstan --- plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php | 2 +- plugins/optimization-detective/class-od-link-collection.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php b/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php index 4558031ff9..77cdf35b52 100644 --- a/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php +++ b/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php @@ -224,7 +224,7 @@ private function reduce_layout_shifts( OD_Tag_Visitor_Context $context ): void { * @param OD_HTML_Tag_Processor $processor Processor, with the cursor currently at an embed block. * @return array Array of URLs to preconnect to. */ - private function get_preconnect_urls( OD_HTML_Tag_Processor $processor ): array { + private function get_dns_prefetch_urls( OD_HTML_Tag_Processor $processor ): array { $urls = array(); $has_class = static function ( string $wanted_class ) use ( $processor ): bool { return true === $processor->has_class( $wanted_class ); diff --git a/plugins/optimization-detective/class-od-link-collection.php b/plugins/optimization-detective/class-od-link-collection.php index b8b3d1bf4b..e96587ea5f 100644 --- a/plugins/optimization-detective/class-od-link-collection.php +++ b/plugins/optimization-detective/class-od-link-collection.php @@ -22,7 +22,7 @@ * } * * @phpstan-type LinkAttributes array{ - * rel: 'preload'|'modulepreload'|'preconnect', + * rel: 'preload'|'modulepreload'|'preconnect'|'dns-prefetch', * href?: non-empty-string, * imagesrcset?: non-empty-string, * imagesizes?: non-empty-string, From 879fb25ef057da4756b7bffcc0e0a02357f357ec Mon Sep 17 00:00:00 2001 From: dhruvang21 Date: Mon, 10 Nov 2025 10:43:47 +0530 Subject: [PATCH 4/5] Update code comments --- .../class-embed-optimizer-tag-visitor.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php b/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php index 77cdf35b52..c464ae46a0 100644 --- a/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php +++ b/plugins/embed-optimizer/class-embed-optimizer-tag-visitor.php @@ -104,7 +104,7 @@ public function __invoke( OD_Tag_Visitor_Context $context ): bool { } $this->reduce_layout_shifts( $context ); - $this->add_preconnect_links( $context ); + $this->add_dns_prefetch_links( $context ); $this->lazy_load_embeds( $context ); /* @@ -207,22 +207,22 @@ private function reduce_layout_shifts( OD_Tag_Visitor_Context $context ): void { } /** - * Gets preconnect URLs based on embed type. + * Gets dns-prefech URLs based on embed type. * * The following embeds have been chosen for optimization due to their relative popularity among all embed types. - * The list of hosts being preconnected to was obtained by inserting an embed into a post and then looking + * The list of hosts being dns-prefetched to was obtained by inserting an embed into a post and then looking * at the network log on the frontend as the embed renders. Each should include the host of the iframe src * as well as URLs for assets used by the embed, _if_ the URL looks like it is not geotargeted (e.g. '-us') * or load-balanced (e.g. 's0.example.com'). For the load balancing case, attempt to load the asset by * incrementing the number appearing in the subdomain (e.g. s1.example.com). If the asset still loads, then - * it is a likely case of a load balancing domain name which cannot be safely preconnected since it could + * it is a likely case of a load balancing domain name which cannot be safely dns-prefetched since it could * not end up being the load balanced domain used for the embed. Lastly, these domains are only for the URLs * for GET requests, as POST requests are not likely to be part of the critical rendering path. * * @since 0.4.1 * * @param OD_HTML_Tag_Processor $processor Processor, with the cursor currently at an embed block. - * @return array Array of URLs to preconnect to. + * @return array Array of URLs to dns-prefetch. */ private function get_dns_prefetch_urls( OD_HTML_Tag_Processor $processor ): array { $urls = array(); @@ -277,13 +277,13 @@ private function get_dns_prefetch_urls( OD_HTML_Tag_Processor $processor ): arra } /** - * Adds preconnect links for embed resources. + * Adds dns-prefetch links for embed resources. * * @since 0.4.1 * * @param OD_Tag_Visitor_Context $context Tag visitor context, with the cursor currently at an embed block. */ - private function add_preconnect_links( OD_Tag_Visitor_Context $context ): void { + private function add_dns_prefetch_links( OD_Tag_Visitor_Context $context ): void { $processor = $context->processor; $embed_wrapper_xpath = self::get_embed_wrapper_xpath( $processor->get_xpath() ); From 7e04b2fee6a15bf5598745bfe04093acde997e9a Mon Sep 17 00:00:00 2001 From: dhruvang21 Date: Mon, 10 Nov 2025 10:52:44 +0530 Subject: [PATCH 5/5] Fix: phpunit test cases --- .../all-embeds-inside-viewport/expected.html | 46 +++++++++---------- .../expected.html | 4 +- .../expected.html | 4 +- .../expected.html | 4 +- .../expected.html | 4 +- .../expected.html | 8 ++-- .../expected.html | 8 ++-- .../expected.html | 4 +- .../expected.html | 4 +- .../expected.html | 4 +- 10 files changed, 45 insertions(+), 45 deletions(-) diff --git a/plugins/embed-optimizer/tests/test-cases/all-embeds-inside-viewport/expected.html b/plugins/embed-optimizer/tests/test-cases/all-embeds-inside-viewport/expected.html index 548fc3b3b6..bc851ca48c 100644 --- a/plugins/embed-optimizer/tests/test-cases/all-embeds-inside-viewport/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/all-embeds-inside-viewport/expected.html @@ -67,29 +67,29 @@ @media (782px < width) { #embed-optimizer-2991a426fba8bcbb357e597bb75f154a { min-height: 500px; } } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport-one-group/expected.html b/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport-one-group/expected.html index 0274428000..7457d008a4 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport-one-group/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport-one-group/expected.html @@ -8,8 +8,8 @@ #embed-optimizer-6040306707fb51ccaafa915c2da8f412 { min-height: 500px; } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport-without-resized-data/expected.html b/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport-without-resized-data/expected.html index 1a7a13c4a9..9a77b913d3 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport-without-resized-data/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport-without-resized-data/expected.html @@ -4,8 +4,8 @@ ... - - + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport/expected.html b/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport/expected.html index 8c95b32c72..0c7522ea44 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-inside-viewport/expected.html @@ -11,8 +11,8 @@ @media (782px < width) { #embed-optimizer-6040306707fb51ccaafa915c2da8f412 { min-height: 500px; } } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-outside-viewport-on-mobile/expected.html b/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-outside-viewport-on-mobile/expected.html index 689a873d37..bb8687b69d 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-outside-viewport-on-mobile/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-twitter-embed-outside-viewport-on-mobile/expected.html @@ -11,8 +11,8 @@ @media (782px < width) { #embed-optimizer-6040306707fb51ccaafa915c2da8f412 { min-height: 800px; } } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-wordpress-tv-embed-inside-viewport/expected.html b/plugins/embed-optimizer/tests/test-cases/single-wordpress-tv-embed-inside-viewport/expected.html index d66299d0ea..6c773e3b44 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-wordpress-tv-embed-inside-viewport/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-wordpress-tv-embed-inside-viewport/expected.html @@ -11,10 +11,10 @@ @media (782px < width) { #embed-optimizer-6040306707fb51ccaafa915c2da8f412 { min-height: 500px; } } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - - - + + + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-wordpress-tv-embed-outside-viewport-on-mobile/expected.html b/plugins/embed-optimizer/tests/test-cases/single-wordpress-tv-embed-outside-viewport-on-mobile/expected.html index b4b1cf6857..0c77a03539 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-wordpress-tv-embed-outside-viewport-on-mobile/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-wordpress-tv-embed-outside-viewport-on-mobile/expected.html @@ -11,10 +11,10 @@ @media (782px < width) { #embed-optimizer-6040306707fb51ccaafa915c2da8f412 { min-height: 800px; } } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - - - + + + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-inside-viewport-with-only-mobile-url-metrics/expected.html b/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-inside-viewport-with-only-mobile-url-metrics/expected.html index 84c4b4721a..150b742e78 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-inside-viewport-with-only-mobile-url-metrics/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-inside-viewport-with-only-mobile-url-metrics/expected.html @@ -8,8 +8,8 @@ @media (width <= 480px) { #embed-optimizer-6040306707fb51ccaafa915c2da8f412 { min-height: 500px; } } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-inside-viewport/expected.html b/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-inside-viewport/expected.html index 963505b1b1..15a1be436e 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-inside-viewport/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-inside-viewport/expected.html @@ -11,8 +11,8 @@ @media (782px < width) { #embed-optimizer-6040306707fb51ccaafa915c2da8f412 { min-height: 500px; } } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - + +
diff --git a/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-outside-viewport-on-mobile/expected.html b/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-outside-viewport-on-mobile/expected.html index ce7e210703..42f29ec08c 100644 --- a/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-outside-viewport-on-mobile/expected.html +++ b/plugins/embed-optimizer/tests/test-cases/single-youtube-embed-outside-viewport-on-mobile/expected.html @@ -11,8 +11,8 @@ @media (782px < width) { #embed-optimizer-6040306707fb51ccaafa915c2da8f412 { min-height: 500px; } } /*# sourceURL=embed-optimizer-reduce-layout-shifts */ - - + +