Skip to content
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

Add fetchpriority=high to IMG when it is the LCP element on desktop and mobile with other viewport groups empty #1723

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
return array(
'set_up' => static function ( Test_Image_Prioritizer_Helper $test_case ): void {
$breakpoint_max_widths = array( 480, 600, 782 );

add_filter(
'od_breakpoint_max_widths',
static function () use ( $breakpoint_max_widths ) {
return $breakpoint_max_widths;
}
);

OD_URL_Metrics_Post_Type::store_url_metric(
od_get_url_metrics_slug( od_get_normalized_query_vars() ),
$test_case->get_sample_url_metric(
array(
'viewport_width' => 375,
'elements' => array(
array(
'xpath' => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::IMG]',
'isLCP' => true,
),
),
)
)
);

OD_URL_Metrics_Post_Type::store_url_metric(
od_get_url_metrics_slug( od_get_normalized_query_vars() ),
$test_case->get_sample_url_metric(
array(
'viewport_width' => 1000,
'elements' => array(
array(
'xpath' => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::IMG]',
'isLCP' => true,
),
),
)
)
);
},
'buffer' => '
<html lang="en">
<head>
<meta charset="utf-8">
<title>...</title>
</head>
<body>
<img src="https://example.com/foo.jpg" alt="Foo" width="1200" height="800" fetchpriority="high">
</body>
</html>
',
'expected' => '
<html lang="en">
<head>
<meta charset="utf-8">
<title>...</title>
<link data-od-added-tag rel="preload" fetchpriority="high" as="image" href="https://example.com/foo.jpg" media="screen and (max-width: 480px)">
<link data-od-added-tag rel="preload" fetchpriority="high" as="image" href="https://example.com/foo.jpg" media="screen and (min-width: 783px)">
</head>
<body>
<img data-od-fetchpriority-already-added data-od-xpath="/*[1][self::HTML]/*[2][self::BODY]/*[1][self::IMG]" src="https://example.com/foo.jpg" alt="Foo" width="1200" height="800" fetchpriority="high">
<script type="module">/* import detect ... */</script>
</body>
</html>
',
);
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ public function get_groups_by_lcp_element( string $xpath ): array {
* Gets common LCP element.
*
* @since 0.3.0
* @since n.e.x.t An LCP element is also considered common if it is the same in the narrowest and widest viewport groups, and all intermediate groups are empty.
*
* @return OD_Element|null Common LCP element if it exists.
*/
Expand All @@ -437,38 +438,40 @@ public function get_common_lcp_element(): ?OD_Element {

$result = ( function () {

// If every group isn't populated, then we can't say whether there is a common LCP element across every viewport group.
if ( ! $this->is_every_group_populated() ) {
// Ensure both the narrowest (first) and widest (last) viewport groups are populated.
$first_group = $this->get_first_group();
$last_group = $this->get_last_group();
if ( $first_group->count() === 0 || $last_group->count() === 0 ) {
return null;
}

// Look at the LCP elements across all the viewport groups.
$groups_by_lcp_element_xpath = array();
$lcp_elements_by_xpath = array();
$group_has_unknown_lcp_element = false;
foreach ( $this->groups as $group ) {
$lcp_element = $group->get_lcp_element();
if ( $lcp_element instanceof OD_Element ) {
$groups_by_lcp_element_xpath[ $lcp_element->get_xpath() ][] = $group;
$lcp_elements_by_xpath[ $lcp_element->get_xpath() ][] = $lcp_element;
} else {
$group_has_unknown_lcp_element = true;
}
}
$first_group_lcp_element = $first_group->get_lcp_element();
$last_group_lcp_element = $last_group->get_lcp_element();

// Validate LCP elements exist and have matching XPaths in the extreme viewport groups.
if (
// All breakpoints share the same LCP element.
1 === count( $groups_by_lcp_element_xpath )
&&
// The breakpoints don't share a common lack of a detected LCP element.
! $group_has_unknown_lcp_element
! $first_group_lcp_element instanceof OD_Element
||
! $last_group_lcp_element instanceof OD_Element
||
$first_group_lcp_element->get_xpath() !== $last_group_lcp_element->get_xpath()
) {
$xpath = key( $lcp_elements_by_xpath );
return null; // No common LCP element across the narrowest and widest viewports.
}

return $lcp_elements_by_xpath[ $xpath ][0];
// Check intermediate viewport groups for conflicting LCP elements.
foreach ( array_slice( $this->groups, 1, -1 ) as $group ) {
$group_lcp_element = $group->get_lcp_element();
if (
$group_lcp_element instanceof OD_Element
&&
$group_lcp_element->get_xpath() !== $first_group_lcp_element->get_xpath()
) {
return null; // Conflicting LCP element found in an intermediate group.
}
}

return null;
return $first_group_lcp_element;
} )();

$this->result_cache[ __FUNCTION__ ] = $result;
Expand Down
Loading