wp_get_loading_optimization_attributes( string $tag_name, array $attr, string $context ): array

In this article

Gets loading optimization attributes.

Description

This function returns an array of attributes that should be merged into the given attributes array to optimize loading performance. Potential attributes returned by this function are:

  • loading attribute with a value of "lazy"
  • fetchpriority attribute with a value of "high"
  • decoding attribute with a value of "async"

If any of these attributes are already present in the given attributes, they will not be modified. Note that no element should have both loading="lazy" and fetchpriority="high", so the function will trigger a warning in case both attributes are present with those values.

Parameters

$tag_namestringrequired
The tag name.
$attrarrayrequired
Array of the attributes for the tag.
$contextstringrequired
Context for the element for which the loading optimization attribute is requested.

Return

array Loading optimization attributes.

Source

		}

		// If the editor for HEICs is Imagick, use it to get the image size.
		if ( $editor instanceof WP_Image_Editor_Imagick ) {
			$size = $editor->get_size();
			return array(
				$size['width'],
				$size['height'],
				IMAGETYPE_HEIC,
				sprintf(
					'width="%d" height="%d"',
					$size['width'],
					$size['height']
				),
				'mime' => 'image/heic',
			);
		}
	}

	// The image could not be parsed.
	return false;
}

/**
 * Extracts meta information about an AVIF file: width, height, bit depth, and number of channels.
 *
 * @since 6.5.0
 *
 * @param string $filename Path to an AVIF file.
 * @return array {
 *     An array of AVIF image information.
 *
 *     @type int|false $width        Image width on success, false on failure.
 *     @type int|false $height       Image height on success, false on failure.
 *     @type int|false $bit_depth    Image bit depth on success, false on failure.
 *     @type int|false $num_channels Image number of channels on success, false on failure.
 * }
 */
function wp_get_avif_info( $filename ) {
	$results = array(
		'width'        => false,
		'height'       => false,
		'bit_depth'    => false,
		'num_channels' => false,
	);

	if ( 'image/avif' !== wp_get_image_mime( $filename ) ) {
		return $results;
	}

	// Parse the file using libavifinfo's PHP implementation.
	require_once ABSPATH . WPINC . '/class-avif-info.php';

	$handle = fopen( $filename, 'rb' );
	if ( $handle ) {
		$parser  = new Avifinfo\Parser( $handle );
		$success = $parser->parse_ftyp() && $parser->parse_file();
		fclose( $handle );
		if ( $success ) {
			$results = $parser->features->primary_item_features;
		}
	}
	return $results;
}

/**
 * Extracts meta information about a WebP file: width, height, and type.
 *
 * @since 5.8.0
 *
 * @param string $filename Path to a WebP file.
 * @return array {
 *     An array of WebP image information.
 *
 *     @type int|false    $width  Image width on success, false on failure.
 *     @type int|false    $height Image height on success, false on failure.
 *     @type string|false $type   The WebP type: one of 'lossy', 'lossless' or 'animated-alpha'.
 *                                False on failure.
 * }
 */
function wp_get_webp_info( $filename ) {
	$width  = false;
	$height = false;
	$type   = false;

	if ( 'image/webp' !== wp_get_image_mime( $filename ) ) {
		return compact( 'width', 'height', 'type' );
	}

	$magic = file_get_contents( $filename, false, null, 0, 40 );

	if ( false === $magic ) {
		return compact( 'width', 'height', 'type' );
	}

	// Make sure we got enough bytes.
	if ( strlen( $magic ) < 40 ) {
		return compact( 'width', 'height', 'type' );
	}

	/*
	 * The headers are a little different for each of the three formats.
	 * Header values based on WebP docs, see https://developers.google.com/speed/webp/docs/riff_container.
	 */
	switch ( substr( $magic, 12, 4 ) ) {
		// Lossy WebP.
		case 'VP8 ':
			$parts  = unpack( 'v2', substr( $magic, 26, 4 ) );
			$width  = (int) ( $parts[1] & 0x3FFF );
			$height = (int) ( $parts[2] & 0x3FFF );
			$type   = 'lossy';
			break;
		// Lossless WebP.
		case 'VP8L':
			$parts  = unpack( 'C4', substr( $magic, 21, 4 ) );
			$width  = (int) ( $parts[1] | ( ( $parts[2] & 0x3F ) << 8 ) ) + 1;
			$height = (int) ( ( ( $parts[2] & 0xC0 ) >> 6 ) | ( $parts[3] << 2 ) | ( ( $parts[4] & 0x03 ) << 10 ) ) + 1;
			$type   = 'lossless';
			break;
		// Animated/alpha WebP.
		case 'VP8X':
			// Pad 24-bit int.
			$width = unpack( 'V', substr( $magic, 24, 3 ) . "\x00" );
			$width = (int) ( $width[1] & 0xFFFFFF ) + 1;
			// Pad 24-bit int.
			$height = unpack( 'V', substr( $magic, 27, 3 ) . "\x00" );
			$height = (int) ( $height[1] & 0xFFFFFF ) + 1;
			$type   = 'animated-alpha';
			break;
	}

	return compact( 'width', 'height', 'type' );
}

/**
 * Gets loading optimization attributes.
 *
 * This function returns an array of attributes that should be merged into the given attributes array to optimize
 * loading performance. Potential attributes returned by this function are:
 * - `loading` attribute with a value of "lazy"
 * - `fetchpriority` attribute with a value of "high"
 * - `decoding` attribute with a value of "async"
 *
 * If any of these attributes are already present in the given attributes, they will not be modified. Note that no
 * element should have both `loading="lazy"` and `fetchpriority="high"`, so the function will trigger a warning in case
 * both attributes are present with those values.
 *
 * @since 6.3.0
 *
 * @global WP_Query $wp_query WordPress Query object.
 *
 * @param string $tag_name The tag name.
 * @param array  $attr     Array of the attributes for the tag.
 * @param string $context  Context for the element for which the loading optimization attribute is requested.
 * @return array Loading optimization attributes.
 */
function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) {
	global $wp_query;

	/**
	 * Filters whether to short-circuit loading optimization attributes.
	 *
	 * Returning an array from the filter will effectively short-circuit the loading of optimization attributes,
	 * returning that value instead.
	 *
	 * @since 6.4.0
	 *
	 * @param array|false $loading_attrs False by default, or array of loading optimization attributes to short-circuit.
	 * @param string      $tag_name      The tag name.
	 * @param array       $attr          Array of the attributes for the tag.
	 * @param string      $context       Context for the element for which the loading optimization attribute is requested.
	 */
	$loading_attrs = apply_filters( 'pre_wp_get_loading_optimization_attributes', false, $tag_name, $attr, $context );

	if ( is_array( $loading_attrs ) ) {
		return $loading_attrs;
	}

	$loading_attrs = array();

	/*
	 * Skip lazy-loading for the overall block template, as it is handled more granularly.
	 * The skip is also applicable for `fetchpriority`.
	 */
	if ( 'template' === $context ) {
		/** This filter is documented in wp-includes/media.php */
		return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
	}

	// For now this function only supports images and iframes.
	if ( 'img' !== $tag_name && 'iframe' !== $tag_name ) {
		/** This filter is documented in wp-includes/media.php */
		return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
	}

	/*
	 * Skip programmatically created images within content blobs as they need to be handled together with the other
	 * images within the post content or widget content.
	 * Without this clause, they would already be considered within their own context which skews the image count and
	 * can result in the first post content image being lazy-loaded or an image further down the page being marked as a
	 * high priority.
	 */
	if (
		'the_content' !== $context && doing_filter( 'the_content' ) ||
		'widget_text_content' !== $context && doing_filter( 'widget_text_content' ) ||
		'widget_block_content' !== $context && doing_filter( 'widget_block_content' )
	) {
		/** This filter is documented in wp-includes/media.php */
		return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );

	}

	/*
	 * Add `decoding` with a value of "async" for every image unless it has a
	 * conflicting `decoding` attribute already present.
	 */
	if ( 'img' === $tag_name ) {
		if ( isset( $attr['decoding'] ) ) {

Changelog

VersionDescription
6.3.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.