Make WordPress Core


Ignore:
Timestamp:
09/25/2023 10:37:00 PM (3 years ago)
Author:
flixos90
Message:

Media: Rely on wp_get_loading_optimization_attributes() to add decoding="async" to images.

The wp_get_loading_optimization_attributes() function was introduced in 6.3, as a single centralized place to control loading optimization attributes for various tags, most importantly images.

This changeset consolidates the decoding="async" optimization, which was added in 6.1, to occur solely as part of wp_get_loading_optimization_attributes(), removing duplicate code and allowing centralized filtering based on [56651].

As part of the change, the wp_img_tag_add_decoding_attr() function has been deprecated. The filter of the same name continues to be maintained for backward compatibility, as before covering only images that are part of a content blob such as post content (the_content).

Props pereirinha, mukesh27, joemcgill, flixos90.
Fixes #58892.
See #53232.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/media.php

    r56680 r56690  
    10611061
    10621062                $default_attr = array(
    1063                         'src'      => $src,
    1064                         'class'    => "attachment-$size_class size-$size_class",
    1065                         'alt'      => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
    1066                         'decoding' => 'async',
     1063                        'src'   => $src,
     1064                        'class' => "attachment-$size_class size-$size_class",
     1065                        'alt'   => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
    10671066                );
    10681067
    … …  
    18931892                        $filtered_image = wp_img_tag_add_loading_optimization_attrs( $filtered_image, $context );
    18941893
    1895                         // Add 'decoding=async' attribute unless a 'decoding' attribute is already present.
    1896                         if ( ! str_contains( $filtered_image, ' decoding=' ) ) {
    1897                                 $filtered_image = wp_img_tag_add_decoding_attr( $filtered_image, $context );
    1898                         }
    1899 
    19001894                        /**
    19011895                         * Filters an img tag within the content for a given context.
    … …  
    19581952        $loading_val       = preg_match( '/ loading=["\']([A-Za-z]+)["\']/', $image, $match_loading ) ? $match_loading[1] : null;
    19591953        $fetchpriority_val = preg_match( '/ fetchpriority=["\']([A-Za-z]+)["\']/', $image, $match_fetchpriority ) ? $match_fetchpriority[1] : null;
     1954        $decoding_val      = preg_match( '/ decoding=["\']([A-Za-z]+)["\']/', $image, $match_decoding ) ? $match_decoding[1] : null;
    19601955
    19611956        /*
    … …  
    19711966                        'loading'       => $loading_val,
    19721967                        'fetchpriority' => $fetchpriority_val,
     1968                        'decoding'      => $decoding_val,
    19731969                ),
    19741970                $context
    19751971        );
    19761972
    1977         // Images should have source and dimension attributes for the loading optimization attributes to be added.
    1978         if ( ! str_contains( $image, ' src="' ) || ! str_contains( $image, ' width="' ) || ! str_contains( $image, ' height="' ) ) {
     1973        // Images should have source for the loading optimization attributes to be added.
     1974        if ( ! str_contains( $image, ' src="' ) ) {
     1975                return $image;
     1976        }
     1977
     1978        if ( empty( $decoding_val ) ) {
     1979                /**
     1980                 * Filters the `decoding` attribute value to add to an image. Default `async`.
     1981                 *
     1982                 * Returning a falsey value will omit the attribute.
     1983                 *
     1984                 * @since 6.1.0
     1985                 *
     1986                 * @param string|false|null $value      The `decoding` attribute value. Returning a falsey value
     1987                 *                                      will result in the attribute being omitted for the image.
     1988                 *                                      Otherwise, it may be: 'async', 'sync', or 'auto'. Defaults to false.
     1989                 * @param string            $image      The HTML `img` tag to be filtered.
     1990                 * @param string            $context    Additional context about how the function was called
     1991                 *                                      or where the img tag is.
     1992                 */
     1993                $filtered_decoding_attr = apply_filters(
     1994                        'wp_img_tag_add_decoding_attr',
     1995                        isset( $optimization_attrs['decoding'] ) ? $optimization_attrs['decoding'] : false,
     1996                        $image,
     1997                        $context
     1998                );
     1999
     2000                // Validate the values after filtering.
     2001                if ( isset( $optimization_attrs['decoding'] ) && ! $filtered_decoding_attr ) {
     2002                        // Unset `decoding` attribute if `$filtered_decoding_attr` is set to `false`.
     2003                        unset( $optimization_attrs['decoding'] );
     2004                } elseif ( in_array( $filtered_decoding_attr, array( 'async', 'sync', 'auto' ), true ) ) {
     2005                        $optimization_attrs['decoding'] = $filtered_decoding_attr;
     2006                }
     2007
     2008                if ( ! empty( $optimization_attrs['decoding'] ) ) {
     2009                        $image = str_replace( '<img', '<img decoding="' . esc_attr( $optimization_attrs['decoding'] ) . '"', $image );
     2010                }
     2011        }
     2012
     2013        // Images should have dimension attributes for the 'loading' and 'fetchpriority' attributes to be added.
     2014        if ( ! str_contains( $image, ' width="' ) || ! str_contains( $image, ' height="' ) ) {
    19792015                return $image;
    19802016        }
    … …  
    20392075        if ( empty( $fetchpriority_val ) && ! empty( $optimization_attrs['fetchpriority'] ) ) {
    20402076                $image = str_replace( '<img', '<img fetchpriority="' . esc_attr( $optimization_attrs['fetchpriority'] ) . '"', $image );
    2041         }
    2042 
    2043         return $image;
    2044 }
    2045 
    2046 /**
    2047  * Adds `decoding` attribute to an `img` HTML tag.
    2048  *
    2049  * The `decoding` attribute allows developers to indicate whether the
    2050  * browser can decode the image off the main thread (`async`), on the
    2051  * main thread (`sync`) or as determined by the browser (`auto`).
    2052  *
    2053  * By default WordPress adds `decoding="async"` to images but developers
    2054  * can use the {@see 'wp_img_tag_add_decoding_attr'} filter to modify this
    2055  * to remove the attribute or set it to another accepted value.
    2056  *
    2057  * @since 6.1.0
    2058  *
    2059  * @param string $image   The HTML `img` tag where the attribute should be added.
    2060  * @param string $context Additional context to pass to the filters.
    2061  *
    2062  * @return string Converted `img` tag with `decoding` attribute added.
    2063  */
    2064 function wp_img_tag_add_decoding_attr( $image, $context ) {
    2065         /*
    2066          * Only apply the decoding attribute to images that have a src attribute that
    2067          * starts with a double quote, ensuring escaped JSON is also excluded.
    2068          */
    2069         if ( ! str_contains( $image, ' src="' ) ) {
    2070                 return $image;
    2071         }
    2072 
    2073         /**
    2074          * Filters the `decoding` attribute value to add to an image. Default `async`.
    2075          *
    2076          * Returning a falsey value will omit the attribute.
    2077          *
    2078          * @since 6.1.0
    2079          *
    2080          * @param string|false|null $value   The `decoding` attribute value. Returning a falsey value
    2081          *                                   will result in the attribute being omitted for the image.
    2082          *                                   Otherwise, it may be: 'async' (default), 'sync', or 'auto'.
    2083          * @param string            $image   The HTML `img` tag to be filtered.
    2084          * @param string            $context Additional context about how the function was called
    2085          *                                   or where the img tag is.
    2086          */
    2087         $value = apply_filters( 'wp_img_tag_add_decoding_attr', 'async', $image, $context );
    2088 
    2089         if ( in_array( $value, array( 'async', 'sync', 'auto' ), true ) ) {
    2090                 $image = str_replace( '<img ', '<img decoding="' . esc_attr( $value ) . '" ', $image );
    20912077        }
    20922078
    … …  
    56095595 * - `loading` attribute with a value of "lazy"
    56105596 * - `fetchpriority` attribute with a value of "high"
     5597 * - `decoding` attribute with a value of "async"
    56115598 *
    56125599 * If any of these attributes are already present in the given attributes, they will not be modified. Note that no
    … …  
    56585645        // For now this function only supports images and iframes.
    56595646        if ( 'img' !== $tag_name && 'iframe' !== $tag_name ) {
    5660                 /** This filter is documented in wp-includes/media.php */
    5661                 return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
    5662         }
    5663 
    5664         // For any resources, width and height must be provided, to avoid layout shifts.
    5665         if ( ! isset( $attr['width'], $attr['height'] ) ) {
    56665647                /** This filter is documented in wp-includes/media.php */
    56675648                return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
    … …  
    56775658        // TODO: Handle shortcode images together with the content (see https://core.trac.wordpress.org/ticket/58853).
    56785659        if ( 'the_content' !== $context && 'do_shortcode' !== $context && doing_filter( 'the_content' ) ) {
     5660                /** This filter is documented in wp-includes/media.php */
     5661                return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
     5662        }
     5663
     5664        /*
     5665         * Add `decoding` with a value of "async" for every image unless it has a
     5666         * conflicting `decoding` attribute already present.
     5667         */
     5668        if ( 'img' === $tag_name ) {
     5669                if ( isset( $attr['decoding'] ) ) {
     5670                        $loading_attrs['decoding'] = $attr['decoding'];
     5671                } else {
     5672                        $loading_attrs['decoding'] = 'async';
     5673                }
     5674        }
     5675
     5676        // For any resources, width and height must be provided, to avoid layout shifts.
     5677        if ( ! isset( $attr['width'], $attr['height'] ) ) {
    56795678                /** This filter is documented in wp-includes/media.php */
    56805679                return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
Note: See TracChangeset for help on using the changeset viewer.