-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorporate breakpoints into preconnect links added by Embed Optimizer #1654
base: trunk
Are you sure you want to change the base?
Incorporate breakpoints into preconnect links added by Embed Optimizer #1654
Conversation
Previously, links were sorted only by `minimum_viewport_width`, which caused issues when merging consecutive preconnect links, especially when dealing with breakpoints and different URLs. This update changes the sorting logic to first sort links by the `href` attribute, grouping identical URLs together. Once grouped, links are then sorted by `minimum_viewport_width`. This ensures that preconnect links are correctly merged when attributes align.
@@ -37,7 +37,7 @@ function od_initialize_extensions(): void { | |||
*/ | |||
function od_generate_media_query( ?int $minimum_viewport_width, ?int $maximum_viewport_width ): ?string { | |||
if ( is_int( $minimum_viewport_width ) && is_int( $maximum_viewport_width ) && $minimum_viewport_width > $maximum_viewport_width ) { | |||
_doing_it_wrong( __FUNCTION__, esc_html__( 'The minimum width must be greater than the maximum width.', 'optimization-detective' ), 'Optimization Detective 0.7.0' ); | |||
_doing_it_wrong( __FUNCTION__, esc_html__( 'The minimum width cannot be greater than the maximum width.', 'optimization-detective' ), 'Optimization Detective 0.7.0' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right 😅
$href_a = $a['attributes']['href'] ?? ''; | ||
$href_b = $b['attributes']['href'] ?? ''; | ||
|
||
$href_comparison = strcmp( $href_a, $href_b ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be the same as:
$href_comparison = ( $href_a <=> $href_b );
Right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe in this case it would be the same.
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
FYI: The screenshot is broken. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good!
Added some feedback.
Let's also add a test case specifically for when there is an embed visible on a desktop viewport but hidden on a mobile viewport.
foreach ( $context->url_metric_group_collection as $group ) { | ||
if ( $group->get_element_max_intersection_ratio( $embed_wrapper_xpath ) <= 0 ) { | ||
continue; | ||
} | ||
|
||
$context->link_collection->add_link( | ||
array( | ||
'rel' => 'preconnect', | ||
'href' => $preconnect_href, | ||
), | ||
$group->get_minimum_viewport_width(), | ||
$group->get_maximum_viewport_width() | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The analogous logic that adds preload links for the LCP image:
performance/plugins/image-prioritizer/class-image-prioritizer-img-tag-visitor.php
Lines 146 to 180 in df29967
foreach ( $context->url_metric_group_collection->get_groups_by_lcp_element( $xpath ) as $group ) { | |
$link_attributes = array_merge( | |
array( | |
'rel' => 'preload', | |
'fetchpriority' => 'high', | |
'as' => 'image', | |
), | |
array_filter( | |
array( | |
'href' => (string) $processor->get_attribute( 'src' ), | |
'imagesrcset' => (string) $processor->get_attribute( 'srcset' ), | |
'imagesizes' => (string) $processor->get_attribute( 'sizes' ), | |
), | |
static function ( string $value ): bool { | |
return '' !== $value; | |
} | |
) | |
); | |
$crossorigin = $this->get_attribute_value( $processor, 'crossorigin' ); | |
if ( null !== $crossorigin ) { | |
$link_attributes['crossorigin'] = 'use-credentials' === $crossorigin ? 'use-credentials' : 'anonymous'; | |
} | |
$link_attributes['media'] = 'screen'; | |
$context->link_collection->add_link( | |
$link_attributes, | |
$group->get_minimum_viewport_width(), | |
$group->get_maximum_viewport_width() | |
); | |
} | |
return true; | |
} |
For that we use $context->url_metric_group_collection->get_groups_by_lcp_element()
to get the groups, whereas here it is looping over each group in the collection and then checking for each one whether the current embed is visible in it. So this makes sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a thought: would it make sense to refactor this into a method like get_groups_by_visible_element
? This could encapsulate the logic for finding groups where the element is visible, potentially making the code more modular and readable. However, it does introduce an extra function call. Would you recommend this, or is the current approach preferable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@westonruter I noticed that the analogous code includes $link_attributes['media'] = 'screen';
. However, based on a previous comment you made on another PR, I assume that specifying 'screen' as the media type might not be appropriate in this context. Am I correct in thinking that?
) | ||
); | ||
foreach ( $context->url_metric_group_collection as $group ) { | ||
if ( $group->get_element_max_intersection_ratio( $embed_wrapper_xpath ) <= 0 ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the intersection ratio ever be less than 0? I don't think so, and Gemini confirms. Since we're comparing floats, it's probably not safe to check if the return value is exactly equal to 0. How about:
if ( $group->get_element_max_intersection_ratio( $embed_wrapper_xpath ) <= 0 ) { | |
if ( ! ( $group->get_element_max_intersection_ratio( $embed_wrapper_xpath ) > 0.0 ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. Changed it in 5ecfcf2.
Co-authored-by: Weston Ruter <[email protected]>
Summary
Fixes #1341
For example, if an embed is not visible on mobile:
Relevant technical choices
href
attributes of preconnect links are sorted to group identical URLs together. If the URLs are identical, they are further sorted byminimum_viewport_width
. This strategy enables merging of consecutive links, reducing redundancy. Refer to the discussion in Incorporate breakpoints into preconnect links added by Embed Optimizer #1341 (comment).OD_URL_Metric_Group::get_xpath_elements_map()
,OD_URL_Metric_Group::get_all_element_max_intersection_ratios()
andOD_URL_Metric_Group::get_element_max_intersection_ratio()
methods to help determine if a link should get preconnected on that particular viewport group.