Skip to content

Commit

Permalink
Merge branch 'trunk' of https://github.com/WordPress/performance into…
Browse files Browse the repository at this point in the history
… add/external-bg-preload
  • Loading branch information
westonruter committed Dec 9, 2024
2 parents b8b79de + d13f33c commit 3ac0253
Show file tree
Hide file tree
Showing 8 changed files with 375 additions and 45 deletions.
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
Original file line number Diff line number Diff line change
Expand Up @@ -721,45 +721,119 @@ public function test_get_groups_by_lcp_element(): void {
$this->assertNull( $group_collection->get_common_lcp_element() );
}

/**
* Data provider.
*
* @return array<string, mixed>
*/
public function data_provider_test_get_common_lcp_element(): array {
$xpath1 = '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::IMG]/*[1]';
$xpath2 = '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::IMG]/*[2]';

$get_sample_url_metric = function ( int $viewport_width, string $lcp_element_xpath, bool $is_lcp = true ): OD_URL_Metric {
return $this->get_sample_url_metric(
array(
'viewport_width' => $viewport_width,
'element' => array(
'isLCP' => $is_lcp,
'xpath' => $lcp_element_xpath,
),
)
);
};

return array(
'all_groups_have_common_lcp' => array(
'url_metrics' => array(
$get_sample_url_metric( 400, $xpath1 ),
$get_sample_url_metric( 600, $xpath1 ),
$get_sample_url_metric( 1000, $xpath1 ),
),
'expected' => $xpath1,
),
'no_url_metrics' => array(
'url_metrics' => array(),
'expected' => null,
),
'empty_first_group' => array(
'url_metrics' => array(
$get_sample_url_metric( 600, $xpath1 ),
$get_sample_url_metric( 1000, $xpath1 ),
),
'expected' => null,
),
'empty_last_group' => array(
'url_metrics' => array(
$get_sample_url_metric( 400, $xpath1 ),
$get_sample_url_metric( 600, $xpath1 ),
),
'expected' => null,
),
'first_and_last_common_lcp_others_empty' => array(
'url_metrics' => array(
$get_sample_url_metric( 400, $xpath1 ),
$get_sample_url_metric( 1000, $xpath1 ),
),
'expected' => $xpath1,
),
'intermediate_groups_conflict' => array(
'url_metrics' => array(
$get_sample_url_metric( 400, $xpath1 ),
$get_sample_url_metric( 600, $xpath2 ),
$get_sample_url_metric( 1000, $xpath1 ),
),
'expected' => null,
),
'first_and_last_lcp_mismatch' => array(
'url_metrics' => array(
$get_sample_url_metric( 400, $xpath1 ),
$get_sample_url_metric( 600, $xpath1 ),
$get_sample_url_metric( 1000, $xpath2 ),
),
'expected' => null,
),
'no_lcp_metrics' => array(
'url_metrics' => array(
$get_sample_url_metric( 400, $xpath1, false ),
$get_sample_url_metric( 600, $xpath1, false ),
$get_sample_url_metric( 1000, $xpath1, false ),
),
'expected' => null,
),
);
}

/**
* Test get_common_lcp_element().
*
* @covers ::get_common_lcp_element
*
* @dataProvider data_provider_test_get_common_lcp_element
*
* @param OD_URL_Metric[] $url_metrics URL Metrics.
* @param string|null $expected Expected.
*/
public function test_get_common_lcp_element(): void {
public function test_get_common_lcp_element( array $url_metrics, ?string $expected ): void {
$breakpoints = array( 480, 800 );
$sample_size = 3;
$current_etag = md5( '' );
$group_collection = new OD_URL_Metric_Group_Collection(
array(),
$url_metrics,
$current_etag,
$breakpoints,
$sample_size,
HOUR_IN_SECONDS
);

$lcp_element_xpath = '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::IMG]/*[1]';

foreach ( array_merge( $breakpoints, array( 1000 ) ) as $viewport_width ) {
for ( $i = 0; $i < $sample_size; $i++ ) {
$group_collection->add_url_metric(
$this->get_sample_url_metric(
array(
'viewport_width' => $viewport_width,
'element' => array(
'isLCP' => true,
'xpath' => $lcp_element_xpath,
),
)
)
);
}
}

$this->assertCount( 3, $group_collection );

$common_lcp_element = $group_collection->get_common_lcp_element();
$this->assertInstanceOf( OD_Element::class, $common_lcp_element );
$this->assertSame( $lcp_element_xpath, $common_lcp_element['xpath'] );
if ( is_string( $expected ) ) {
$this->assertInstanceOf( OD_Element::class, $common_lcp_element );
$this->assertSame( $expected, $common_lcp_element->get_xpath() );
} else {
$this->assertNull( $common_lcp_element );
}
}

/**
Expand Down
11 changes: 11 additions & 0 deletions plugins/webp-uploads/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,17 @@ function webp_uploads_is_fallback_enabled(): bool {
return (bool) get_option( 'perflab_generate_webp_and_jpeg' );
}

/**
* Checks if the `perflab_generate_all_fallback_sizes` option is enabled.
*
* @since n.e.x.t
*
* @return bool Whether the option is enabled. Default is false.
*/
function webp_uploads_should_generate_all_fallback_sizes(): bool {
return (bool) get_option( 'perflab_generate_all_fallback_sizes', 0 );
}

/**
* Retrieves the image URL for a specified MIME type from the attachment metadata.
*
Expand Down
21 changes: 21 additions & 0 deletions plugins/webp-uploads/hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -806,3 +806,24 @@ function webp_uploads_opt_in_extra_image_sizes(): void {
}
}
add_action( 'plugins_loaded', 'webp_uploads_opt_in_extra_image_sizes' );

/**
* Enables additional MIME type support for all image sizes based on the generate all fallback sizes settings.
*
* @since n.e.x.t
*
* @param array<string, bool> $allowed_sizes A map of image size names and whether they are allowed to have additional MIME types.
* @return array<string, bool> Modified map of image sizes with additional MIME type support.
*/
function webp_uploads_enable_additional_mime_type_support_for_all_sizes( array $allowed_sizes ): array {
if ( ! webp_uploads_should_generate_all_fallback_sizes() ) {
return $allowed_sizes;
}

foreach ( array_keys( $allowed_sizes ) as $size ) {
$allowed_sizes[ $size ] = true;
}

return $allowed_sizes;
}
add_filter( 'webp_uploads_image_sizes_with_additional_mime_type_support', 'webp_uploads_enable_additional_mime_type_support_for_all_sizes' );
Loading

0 comments on commit 3ac0253

Please sign in to comment.