mirror of
git://develop.git.wordpress.org/
synced 2025-02-06 15:41:08 +01:00
Media: Enhance logic to determine LCP image in block themes and avoid lazy-loading it.
[52065] originally introduced the logic to guess the LCP image based on certain heuristics and to not lazy-load that image. However, with the introduction of block themes, that logic was not functioning correctly, resulting in all featured images to be lazy-loaded, regardless of whether it was the LCP image or not. Together with an update to the `core/post-featured-image` block included in [55079], this changeset fixes the logic to correctly handle featured images in block themes as well. Additionally, in combination with an update to the `core/template-part` block from [55246], this changeset includes an enhancement which uses the benefits of block template parts to avoid lazy-loading images in the `header` block template part, making the lazy-loading heuristics even more accurate for sites using a block theme. Props flixos90, adamsilverstein, mamaduka, antonvlasenko, shahidul95, reduanmasud, costdev, mukesh27, ironprogrammer, manfcarlo, robinwpdeveloper, spacedmonkey. Fixes #56930. git-svn-id: https://develop.svn.wordpress.org/trunk@55318 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
ea57bf06ea
commit
87c575a9fc
@ -241,7 +241,7 @@ function get_the_block_template_html() {
|
||||
$content = wptexturize( $content );
|
||||
$content = convert_smilies( $content );
|
||||
$content = shortcode_unautop( $content );
|
||||
$content = wp_filter_content_tags( $content );
|
||||
$content = wp_filter_content_tags( $content, 'template' );
|
||||
$content = do_shortcode( $content );
|
||||
$content = str_replace( ']]>', ']]>', $content );
|
||||
|
||||
|
@ -5444,25 +5444,40 @@ function wp_get_webp_info( $filename ) {
|
||||
* that the `loading` attribute should be skipped.
|
||||
*/
|
||||
function wp_get_loading_attr_default( $context ) {
|
||||
// Only elements with 'the_content' or 'the_post_thumbnail' context have special handling.
|
||||
if ( 'the_content' !== $context && 'the_post_thumbnail' !== $context ) {
|
||||
return 'lazy';
|
||||
}
|
||||
|
||||
// Only elements within the main query loop have special handling.
|
||||
if ( is_admin() || ! in_the_loop() || ! is_main_query() ) {
|
||||
return 'lazy';
|
||||
}
|
||||
|
||||
// Increase the counter since this is a main query content element.
|
||||
$content_media_count = wp_increase_content_media_count();
|
||||
|
||||
// If the count so far is below the threshold, return `false` so that the `loading` attribute is omitted.
|
||||
if ( $content_media_count <= wp_omit_loading_attr_threshold() ) {
|
||||
// Skip lazy-loading for the overall block template, as it is handled more granularly.
|
||||
if ( 'template' === $context ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For elements after the threshold, lazy-load them as usual.
|
||||
// Do not lazy-load images in the header block template part, as they are likely above the fold.
|
||||
$header_area = WP_TEMPLATE_PART_AREA_HEADER;
|
||||
if ( "template_part_{$header_area}" === $context ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The first elements in 'the_content' or 'the_post_thumbnail' should not be lazy-loaded,
|
||||
* as they are likely above the fold.
|
||||
*/
|
||||
if ( 'the_content' === $context || 'the_post_thumbnail' === $context ) {
|
||||
// Only elements within the main query loop have special handling.
|
||||
if ( is_admin() || ! in_the_loop() || ! is_main_query() ) {
|
||||
return 'lazy';
|
||||
}
|
||||
|
||||
// Increase the counter since this is a main query content element.
|
||||
$content_media_count = wp_increase_content_media_count();
|
||||
|
||||
// If the count so far is below the threshold, return `false` so that the `loading` attribute is omitted.
|
||||
if ( $content_media_count <= wp_omit_loading_attr_threshold() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For elements after the threshold, lazy-load them as usual.
|
||||
return 'lazy';
|
||||
}
|
||||
|
||||
// Lazy-load by default for any unknown context.
|
||||
return 'lazy';
|
||||
}
|
||||
|
||||
|
@ -3547,7 +3547,13 @@ EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that wp_get_loading_attr_default() returns the expected loading attribute value.
|
||||
*
|
||||
* @ticket 53675
|
||||
* @ticket 56930
|
||||
*
|
||||
* @covers ::wp_get_loading_attr_default
|
||||
*
|
||||
* @dataProvider data_wp_get_loading_attr_default
|
||||
*
|
||||
* @param string $context
|
||||
@ -3588,6 +3594,10 @@ EOF;
|
||||
// Yes, for all subsequent elements.
|
||||
$this->assertSame( 'lazy', wp_get_loading_attr_default( $context ) );
|
||||
}
|
||||
|
||||
// Exceptions: In the following contexts, images shouldn't be lazy-loaded by default.
|
||||
$this->assertFalse( wp_get_loading_attr_default( 'template' ), 'Images run through the overall block template filter should not be lazy-loaded.' );
|
||||
$this->assertFalse( wp_get_loading_attr_default( 'template_part_' . WP_TEMPLATE_PART_AREA_HEADER ), 'Images in the footer block template part should not be lazy-loaded.' );
|
||||
}
|
||||
|
||||
public function data_wp_get_loading_attr_default() {
|
||||
@ -3700,6 +3710,159 @@ EOF;
|
||||
$this->assertSame( 3, $omit_threshold );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that wp_filter_content_tags() does not add loading="lazy" to the first
|
||||
* image in the loop when using a block theme.
|
||||
*
|
||||
* @ticket 56930
|
||||
*
|
||||
* @covers ::wp_filter_content_tags
|
||||
* @covers ::wp_get_loading_attr_default
|
||||
*/
|
||||
public function test_wp_filter_content_tags_does_not_lazy_load_first_image_in_block_theme() {
|
||||
global $_wp_current_template_content, $wp_query, $wp_the_query, $post;
|
||||
|
||||
// Do not add srcset, sizes, or decoding attributes as they are irrelevant for this test.
|
||||
add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' );
|
||||
add_filter( 'wp_img_tag_add_decoding_attr', '__return_false' );
|
||||
|
||||
$img1 = get_image_tag( self::$large_id, '', '', '', 'large' );
|
||||
$img2 = get_image_tag( self::$large_id, '', '', '', 'medium' );
|
||||
$lazy_img2 = wp_img_tag_add_loading_attr( $img2, 'the_content' );
|
||||
|
||||
// Only the second image should be lazy-loaded.
|
||||
$post_content = $img1 . $img2;
|
||||
$expected_content = wpautop( $img1 . $lazy_img2 );
|
||||
|
||||
// Update the post to test with so that it has the above post content.
|
||||
wp_update_post(
|
||||
array(
|
||||
'ID' => self::$post_ids['publish'],
|
||||
'post_content' => $post_content,
|
||||
'post_content_filtered' => $post_content,
|
||||
)
|
||||
);
|
||||
|
||||
$wp_query = new WP_Query( array( 'p' => self::$post_ids['publish'] ) );
|
||||
$wp_the_query = $wp_query;
|
||||
$post = get_post( self::$post_ids['publish'] );
|
||||
$this->reset_content_media_count();
|
||||
$this->reset_omit_loading_attr_filter();
|
||||
|
||||
$_wp_current_template_content = '<!-- wp:post-content /-->';
|
||||
|
||||
$html = get_the_block_template_html();
|
||||
$this->assertSame( '<div class="wp-site-blocks"><div class="entry-content wp-block-post-content is-layout-flow">' . $expected_content . '</div></div>', $html );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that wp_filter_content_tags() does not add loading="lazy"
|
||||
* to the featured image when using a block theme.
|
||||
*
|
||||
* @ticket 56930
|
||||
*
|
||||
* @covers ::wp_filter_content_tags
|
||||
* @covers ::wp_get_loading_attr_default
|
||||
*/
|
||||
public function test_wp_filter_content_tags_does_not_lazy_load_first_featured_image_in_block_theme() {
|
||||
global $_wp_current_template_content, $wp_query, $wp_the_query, $post;
|
||||
|
||||
// Do not add srcset, sizes, or decoding attributes as they are irrelevant for this test.
|
||||
add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' );
|
||||
add_filter( 'wp_img_tag_add_decoding_attr', '__return_false' );
|
||||
add_filter(
|
||||
'wp_get_attachment_image_attributes',
|
||||
function( $attr ) {
|
||||
unset( $attr['srcset'], $attr['sizes'], $attr['decoding'] );
|
||||
return $attr;
|
||||
}
|
||||
);
|
||||
|
||||
$content_img = get_image_tag( self::$large_id, '', '', '', 'large' );
|
||||
$lazy_content_img = wp_img_tag_add_loading_attr( $content_img, 'the_content' );
|
||||
|
||||
// The featured image should not be lazy-loaded as it is the first image.
|
||||
$featured_image_id = self::$large_id;
|
||||
update_post_meta( self::$post_ids['publish'], '_thumbnail_id', $featured_image_id );
|
||||
$expected_featured_image = '<figure class="wp-block-post-featured-image">' . get_the_post_thumbnail( self::$post_ids['publish'], 'post-thumbnail', array( 'loading' => false ) ) . '</figure>';
|
||||
|
||||
// The post content image should be lazy-loaded since the featured image appears above.
|
||||
$post_content = $content_img;
|
||||
$expected_content = wpautop( $lazy_content_img );
|
||||
|
||||
// Update the post to test with so that it has the above post content.
|
||||
wp_update_post(
|
||||
array(
|
||||
'ID' => self::$post_ids['publish'],
|
||||
'post_content' => $post_content,
|
||||
'post_content_filtered' => $post_content,
|
||||
)
|
||||
);
|
||||
|
||||
$wp_query = new WP_Query( array( 'p' => self::$post_ids['publish'] ) );
|
||||
$wp_the_query = $wp_query;
|
||||
$post = get_post( self::$post_ids['publish'] );
|
||||
$this->reset_content_media_count();
|
||||
$this->reset_omit_loading_attr_filter();
|
||||
|
||||
$_wp_current_template_content = '<!-- wp:post-featured-image /--> <!-- wp:post-content /-->';
|
||||
|
||||
$html = get_the_block_template_html();
|
||||
$this->assertSame( '<div class="wp-site-blocks">' . $expected_featured_image . ' <div class="entry-content wp-block-post-content is-layout-flow">' . $expected_content . '</div></div>', $html );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that wp_filter_content_tags() does not add loading="lazy" to images
|
||||
* in a "Header" template part.
|
||||
*
|
||||
* @ticket 56930
|
||||
*
|
||||
* @covers ::wp_filter_content_tags
|
||||
* @covers ::wp_get_loading_attr_default
|
||||
*/
|
||||
public function test_wp_filter_content_tags_does_not_lazy_load_images_in_header() {
|
||||
global $_wp_current_template_content;
|
||||
|
||||
// Do not add srcset, sizes, or decoding attributes as they are irrelevant for this test.
|
||||
add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' );
|
||||
add_filter( 'wp_img_tag_add_decoding_attr', '__return_false' );
|
||||
|
||||
// Use a single image for each header and footer template parts.
|
||||
$header_img = get_image_tag( self::$large_id, '', '', '', 'large' );
|
||||
$footer_img = get_image_tag( self::$large_id, '', '', '', 'medium' );
|
||||
|
||||
// Create header and footer template parts.
|
||||
$header_post_id = self::factory()->post->create(
|
||||
array(
|
||||
'post_type' => 'wp_template_part',
|
||||
'post_status' => 'publish',
|
||||
'post_name' => 'header',
|
||||
'post_content' => $header_img,
|
||||
)
|
||||
);
|
||||
wp_set_post_terms( $header_post_id, WP_TEMPLATE_PART_AREA_HEADER, 'wp_template_part_area' );
|
||||
wp_set_post_terms( $header_post_id, get_stylesheet(), 'wp_theme' );
|
||||
$footer_post_id = self::factory()->post->create(
|
||||
array(
|
||||
'post_type' => 'wp_template_part',
|
||||
'post_status' => 'publish',
|
||||
'post_name' => 'footer',
|
||||
'post_content' => $footer_img,
|
||||
)
|
||||
);
|
||||
wp_set_post_terms( $footer_post_id, WP_TEMPLATE_PART_AREA_FOOTER, 'wp_template_part_area' );
|
||||
wp_set_post_terms( $footer_post_id, get_stylesheet(), 'wp_theme' );
|
||||
|
||||
$_wp_current_template_content = '<!-- wp:template-part {"slug":"header","theme":"' . get_stylesheet() . '","tagName":"header"} /--><!-- wp:template-part {"slug":"footer","theme":"' . get_stylesheet() . '","tagName":"footer"} /-->';
|
||||
|
||||
// Header image should not be lazy-loaded, footer image should be lazy-loaded.
|
||||
$expected_template_content = '<header class="wp-block-template-part">' . $header_img . '</header>';
|
||||
$expected_template_content .= '<footer class="wp-block-template-part">' . wp_img_tag_add_loading_attr( $footer_img, 'force-lazy' ) . '</footer>';
|
||||
|
||||
$html = get_the_block_template_html();
|
||||
$this->assertSame( '<div class="wp-site-blocks">' . $expected_template_content . '</div>', $html );
|
||||
}
|
||||
|
||||
private function reset_content_media_count() {
|
||||
// Get current value without increasing.
|
||||
$content_media_count = wp_increase_content_media_count( 0 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user