Make WordPress Core


Ignore:
Timestamp:
09/25/2023 10:37:00 PM (8 months 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.