From ebd03692e64d63803ad3fed2676dfb3cd4631f26 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Wed, 5 Jul 2023 21:36:23 +0000 Subject: [PATCH] Media: Ensure that large images before the main query loop are counted towards lazy-loading threshold. Following [55318], [55847], and [56142], certain images in the header of the page have received support for potentially receiving `fetchpriority="high"` and having the `loading="lazy"` attribute omitted. However, these images being present did not affect the "content media count" which counts the images towards a certain threshold so that the first ones are not lazy-loaded. This changeset also increases that count for such header images if they are larger than a certain threshold. The threshold is used to avoid e.g. a header with lots of small images such as icon graphics to skew the lazy-loading behavior. Props thekt12, spacedmonkey, flixos90. Fixes #58635. git-svn-id: https://develop.svn.wordpress.org/trunk@56143 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/media.php | 15 +++++++++++ tests/phpunit/tests/media.php | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index 0da68e3d43..11815e65fa 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -5588,6 +5588,15 @@ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) { } return $loading_attributes; }; + // Closure to increase media count for images with certain minimum threshold, mostly used for header images. + $maybe_increase_content_media_count = static function() use ( $attr ) { + /** This filter is documented in wp-admin/includes/media.php */ + $wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 ); + // Images with a certain minimum size in the header of the page are also counted towards the threshold. + if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) { + wp_increase_content_media_count(); + } + }; $loading_attrs = array(); @@ -5640,11 +5649,15 @@ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) { */ $header_area = WP_TEMPLATE_PART_AREA_HEADER; if ( "template_part_{$header_area}" === $context ) { + // Increase media count if there are images in header above a certian minimum size threshold. + $maybe_increase_content_media_count(); return $postprocess( $loading_attrs, true ); } // The custom header image is always expected to be in the header. if ( 'get_header_image_tag' === $context ) { + // Increase media count if there are images in header above a certian minimum size threshold. + $maybe_increase_content_media_count(); return $postprocess( $loading_attrs, true ); } @@ -5671,6 +5684,8 @@ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) { */ && did_action( 'get_header' ) && ! did_action( 'get_footer' ) ) { + // Increase media count if there are images in header above a certian minimum size threshold. + $maybe_increase_content_media_count(); return $postprocess( $loading_attrs, true ); } } diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 2fcbe2264f..41c1598a0e 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -5094,6 +5094,55 @@ EOF; ); } + /** + * @ticket 58635 + * + * @covers ::wp_get_loading_optimization_attributes + */ + public function test_wp_get_loading_optimization_attributes_header_block_template_increase_media_count() { + $attr = $this->get_width_height_for_high_priority(); + wp_get_loading_optimization_attributes( 'img', $attr, 'template_part_' . WP_TEMPLATE_PART_AREA_HEADER ); + + // Images with a certain minimum size in the header of the page are also counted towards the threshold. + $this->assertSame( 1, wp_increase_content_media_count( 0 ) ); + } + + /** + * @ticket 58635 + * + * @covers ::wp_get_loading_optimization_attributes + */ + public function test_wp_get_loading_optimization_attributes_header_image_tag_increase_media_count() { + $attr = $this->get_width_height_for_high_priority(); + wp_get_loading_optimization_attributes( 'img', $attr, 'get_header_image_tag' ); + + // Images with a certain minimum size in the header of the page are also counted towards the threshold. + $this->assertSame( 1, wp_increase_content_media_count( 0 ) ); + } + + /** + * @ticket 58635 + * + * @covers ::wp_get_loading_optimization_attributes + * + * @dataProvider data_wp_get_loading_attr_default_before_and_no_loop + * + * @param string $context Context for the element for which the `loading` attribute value is requested. + */ + public function test_wp_get_loading_optimization_attributes_image_before_loop_increase_media_count( $context ) { + global $wp_query; + + $wp_query = $this->get_new_wp_query_for_published_post(); + $this->set_main_query( $wp_query ); + do_action( 'get_header' ); + + $attr = $this->get_width_height_for_high_priority(); + wp_get_loading_optimization_attributes( 'img', $attr, $context ); + + // Images with a certain minimum size in the header of the page are also counted towards the threshold. + $this->assertSame( 1, wp_increase_content_media_count( 0 ) ); + } + /** * Helper method to keep track of the last context returned by the 'wp_get_attachment_image_context' filter. *