Media: Add decoding="async" to image attributes.

Dynamically add `decoding="async"` to image tags on the front end of a site to instruct browsers to download them in parallel.

Modifies `wp_get_attachment_image()`, `get_avatar()` to include the attribute by default. Modifies `wp_filter_content_tags()` to add the attribute during the front-end render of the site.

Introduces `wp_img_tag_add_decoding_attr()` to take an image tag and modify it to include the attribute. Introduces the filter `wp_img_tag_add_decoding_attr` used to define the default value for the attribute.

Props adamsilverstein, ayeshrajans, costdev, flixos90, hellofromtonya, isaumya, michaelbourne, mihai2u, mitogh, sergiomdgomes, spacedmonkey, westonruter, peterwilsoncc.
Fixes #53232.

Built from https://develop.svn.wordpress.org/trunk@53480


git-svn-id: http://core.svn.wordpress.org/trunk@53069 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Peter Wilson 2022-06-09 05:31:12 +00:00
parent cf5df71b88
commit b8e44627c8
3 changed files with 70 additions and 14 deletions

View File

@ -1011,16 +1011,18 @@ function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon
* @param string|array $attr {
* Optional. Attributes for the image markup.
*
* @type string $src Image attachment URL.
* @type string $class CSS class name or space-separated list of classes.
* Default `attachment-$size_class size-$size_class`,
* where `$size_class` is the image size being requested.
* @type string $alt Image description for the alt attribute.
* @type string $srcset The 'srcset' attribute value.
* @type string $sizes The 'sizes' attribute value.
* @type string|false $loading The 'loading' attribute value. Passing a value of false
* will result in the attribute being omitted for the image.
* Defaults to 'lazy', depending on wp_lazy_loading_enabled().
* @type string $src Image attachment URL.
* @type string $class CSS class name or space-separated list of classes.
* Default `attachment-$size_class size-$size_class`,
* where `$size_class` is the image size being requested.
* @type string $alt Image description for the alt attribute.
* @type string $srcset The 'srcset' attribute value.
* @type string $sizes The 'sizes' attribute value.
* @type string|false $loading The 'loading' attribute value. Passing a value of false
* will result in the attribute being omitted for the image.
* Defaults to 'lazy', depending on wp_lazy_loading_enabled().
* @type string $decoding The 'decoding' attribute value. Possible values are
* 'async' (default), 'sync', or 'auto'.
* }
* @return string HTML img element or empty string on failure.
*/
@ -1040,9 +1042,10 @@ function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = f
}
$default_attr = array(
'src' => $src,
'class' => "attachment-$size_class size-$size_class",
'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
'src' => $src,
'class' => "attachment-$size_class size-$size_class",
'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
'decoding' => 'async',
);
// Add `loading` attribute.
@ -1843,6 +1846,11 @@ function wp_filter_content_tags( $content, $context = null ) {
$filtered_image = wp_img_tag_add_loading_attr( $filtered_image, $context );
}
// Add 'decoding=async' attribute unless a 'decoding' attribute is already present.
if ( ! str_contains( $filtered_image, ' decoding=' ) ) {
$filtered_image = wp_img_tag_add_decoding_attr( $filtered_image, $context );
}
/**
* Filters an img tag within the content for a given context.
*
@ -1934,6 +1942,46 @@ function wp_img_tag_add_loading_attr( $image, $context ) {
return $image;
}
/**
* Add `decoding` attribute to an `img` HTML tag.
*
* The `decoding` attribute allows developers to indicate whether the
* browser can decode the image off the main thread (`async`), on the
* main thread (`sync`) or as determined by the browser (`auto`).
*
* By default WordPress adds `decoding="async"` to images but developers
* can use the {@see 'wp_img_tag_add_decoding_attr'} filter to modify this
* to remove the attribute or set it to another accepted value.
*
* @since 6.1.0
*
* @param string $image The HTML `img` tag where the attribute should be added.
* @param string $context Additional context to pass to the filters.
*
* @return string Converted `img` tag with `decoding` attribute added.
*/
function wp_img_tag_add_decoding_attr( $image, $context ) {
/**
* Filters the `decoding` attribute value to add to an image. Default `async`.
*
* Returning a falsey value will omit the attribute.
*
* @since 6.1.0
*
* @param string|false|null $value The `decoding` attribute value. Returning a falsey value will result in
* the attribute being omitted for the image. Otherwise, it may be:
* 'async' (default), 'sync', or 'auto'.
* @param string $image The HTML `img` tag to be filtered.
* @param string $context Additional context about how the function was called or where the img tag is.
*/
$value = apply_filters( 'wp_img_tag_add_decoding_attr', 'async', $image, $context );
if ( in_array( $value, array( 'async', 'sync', 'auto' ), true ) ) {
$image = str_replace( '<img ', '<img decoding="' . esc_attr( $value ) . '" ', $image );
}
return $image;
}
/**
* Adds `width` and `height` attributes to an `img` HTML tag.
*

View File

@ -2764,6 +2764,7 @@ if ( ! function_exists( 'get_avatar' ) ) :
'force_display' => false,
'loading' => null,
'extra_attr' => '',
'decoding' => 'async',
);
if ( wp_lazy_loading_enabled( 'img', 'get_avatar' ) ) {
@ -2851,6 +2852,13 @@ if ( ! function_exists( 'get_avatar' ) ) :
$extra_attr .= "loading='{$loading}'";
}
if ( in_array( $args['decoding'], array( 'async', 'sync', 'auto' ) ) && ! preg_match( '/\bdecoding\s*=/', $extra_attr ) ) {
if ( ! empty( $extra_attr ) ) {
$extra_attr .= ' ';
}
$extra_attr .= "decoding='{$args['decoding']}'";
}
$avatar = sprintf(
"<img alt='%s' src='%s' srcset='%s' class='%s' height='%d' width='%d' %s/>",
esc_attr( $args['alt'] ),

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.1-alpha-53479';
$wp_version = '6.1-alpha-53480';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.