# wp_get_loading_optimization_attributes()

URL: https://chugunov.pro/api-wordpress/functions/wp_get_loading_optimization_attributes/
Проверено на WordPress 6.9, обновлено 06.08.2026.
Источник: независимый русскоязычный справочник chugunov.pro. Не является официальной документацией WordPress.

Тип: функция.
Появился в версии: 6.3.0.

## Сигнатура

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

## Описание

Эта функция возвращает массив атрибутов, которые следует объединить с заданным массивом атрибутов для оптимизации производительности загрузки. Возможные возвращаемые атрибуты:

атрибут loading со значением «lazy»

атрибут fetchpriority со значением «high»

атрибут decoding со значением «async»

Если какой-либо из этих атрибутов уже присутствует в заданных атрибутах, он не будет изменён. Обратите внимание, что ни у одного элемента не должно быть одновременно loading="lazy" и fetchpriority="high", поэтому при наличии обоих атрибутов с такими значениями функция выдаст предупреждение.

## Параметры

- `$tag_name` `string` — обязательный. Имя тега.
- `$attr` `array` — обязательный. Массив атрибутов тега.
- `$context` `string` — обязательный. Контекст элемента, для которого запрашивается атрибут оптимизации загрузки.

## Возвращаемое значение

`array`

## Исходный код

Файл: `wp-includes/media.php:5979`

```php
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 ) {
		$loading_attrs['decoding'] = $attr['decoding'] ?? 'async';
	}

	// For any resources, width and height must be provided, to avoid layout shifts.
	if ( ! isset( $attr['width'], $attr['height'] ) ) {
		/** This filter is documented in wp-includes/media.php */
		return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
	}

	/*
	 * The key function logic starts here.
	 */
	$maybe_in_viewport    = null;
	$increase_count       = false;
	$maybe_increase_count = false;

	// Logic to handle a `loading` attribute that is already provided.
	if ( isset( $attr['loading'] ) ) {
		/*
		 * Interpret "lazy" as not in viewport. Any other value can be
		 * interpreted as in viewport (realistically only "eager" or `false`
		 * to force-omit the attribute are other potential values).
		 */
		if ( 'lazy' === $attr['loading'] ) {
			$maybe_in_viewport = false;
		} else {
			$maybe_in_viewport = true;
		}
	}

	// Logic to handle a `fetchpriority` attribute that is already provided.
	$existing_fetchpriority = ( $attr['fetchpriority'] ?? null );
	$is_low_fetchpriority   = ( 'low' === $existing_fetchpriority );
	if ( 'high' === $existing_fetchpriority ) {
		/*
		 * If the image was already determined to not be in the viewport (e.g.
		 * from an already provided `loading` attribute), trigger a warning.
		 * Otherwise, the value can be interpreted as in viewport, since only
		 * the most important in-viewport image should have `fetchpriority` set
		 * to "high".
		 */
		if ( false === $maybe_in_viewport ) {
			_doing_it_wrong(
				__FUNCTION__,
				__( 'An image should not be lazy-loaded and marked as high priority at the same time.' ),
				'6.3.0'
			);
			/*
			 * Set `fetchpriority` here for backward-compatibility as we should
			 * not override what a developer decided, even though it seems
			 * incorrect.
			 */
			$loading_attrs['fetchpriority'] = 'high';
		} else {
			$maybe_in_viewport = true;
		}
	} elseif ( $is_low_fetchpriority ) {
		/*
		 * An IMG with fetchpriority=low is not initially displayed; it may be hidden in the Navigation Overlay,
		 * or it may be occluded in a non-initial carousel slide. Such images must not be lazy-loaded because the browser
		 * has no heuristic to know when to start loading them before the user needs to see them.
		 */
		$maybe_in_viewport = false;

		// Preserve fetchpriority=low.
		$loading_attrs['fetchpriority'] = 'low';
	} elseif ( 'auto' === $existing_fetchpriority ) {
		/*
		 * When a block's visibility support identifies that the block is conditionally displayed based on the viewport
		 * size, then it adds `fetchpriority=auto` to the block's IMG tags. These images must not be fetched with high
		 * priority because they could be erroneously loaded in viewports which do not even display them. Contrarily,
		 * they must not get `fetchpriority=low` because they may in fact be displayed in the current viewport. So as
		 * a signal to indicate that an IMG may be in the viewport, `fetchpriority=auto` is added. This has the effect
		 * here of preventing the media count from being increased, so that images hidden with block visibility do not
		 * affect whether a following IMG gets `loading=lazy`. In particular, `loading=lazy` should still be omitted
		 * on an IMG following any number of initial IMGs with `fetchpriority=auto` since those initial images may not
		 * be displayed.
		 */

		// Preserve fetchpriority=auto.
		$loading_attrs['fetchpriority'] = 'auto';
	}

	if ( null === $maybe_in_viewport ) {
		$header_enforced_contexts = array(
			'template_part_' . WP_TEMPLATE_PART_AREA_HEADER => true,
			'get_header_image_tag' => true,
		);

		/**
		 * Filters the header-specific contexts.
		 *
		 * @since 6.4.0
		 *
		 * @param array $default_header_enforced_contexts Map of contexts for which elements should be considered
		 *                                                in the header of the page, as $context => $enabled
		 *                                                pairs. The $enabled should always be true.
		 */
		$header_enforced_contexts = apply_filters( 'wp_loading_optimization_force_header_contexts', $header_enforced_contexts );

		// Consider elements with these header-specific contexts to be in viewport.
		if ( isset( $header_enforced_contexts[ $context ] ) ) {
			$maybe_in_viewport    = true;
			$maybe_increase_count = true;
		} elseif ( ! is_admin() && in_the_loop() && is_main_query() ) {
			/*
			 * Get the content media count, since this is a main query
			 * content element. This is accomplished by "increasing"
			 * the count by zero, as the only way to get the count is
			 * to call this function.
			 * The actual count increase happens further below, based
			 * on the `$increase_count` flag set here.
			 */
			$content_media_count = wp_increase_content_media_count( 0 );
			$increase_count      = true;

			// If the count so far is below the threshold, `loading` attribute is omitted.
			if ( $content_media_count < wp_omit_loading_attr_threshold() ) {
				$maybe_in_viewport = true;
			} else {
				$maybe_in_viewport = false;
			}
		} elseif (
			// Only apply for main query but before the loop.
			$wp_query->before_loop && $wp_query->is_main_query()
			/*
			 * Any image before the loop, but after the header has started should not be lazy-loaded,
			 * except when the footer has already started which can happen when the current template
			 * does not include any loop.
			 */
			&& did_action( 'get_header' ) && ! did_action( 'get_footer' )
		) {
			$maybe_in_viewport    = true;
			$maybe_increase_count = true;
		}
	}

	/*
	 * If the element is in the viewport (`true`), potentially add
	 * `fetchpriority` with a value of "high". Otherwise, i.e. if the element
	 * is not in the viewport (`false`) or it is unknown (`null`), add
	 * `loading` with a value of "lazy" if the element is not already being
	 * de-prioritized with `fetchpriority=low` due to occlusion in
	 * Navigation Overlay, non-initial carousel slides, or a collapsed Details block.
	 */
	if ( $maybe_in_viewport ) {
		$loading_attrs = wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr );
	} elseif ( ! $is_low_fetchpriority ) {
		// Only add `loading="lazy"` if the feature is enabled.
		if ( wp_lazy_loading_enabled( $tag_name, $context ) ) {
			$loading_attrs['loading'] = 'lazy';
		}
	}

	/*
	 * If flag was set based on contextual logic above, increase the content
	 * media count, either unconditionally, or based on whether the image size
	 * is larger than the threshold. This does not apply when the IMG has
	 * fetchpriority=auto because it may be conditionally displayed by viewport
	 * size.
	 */
	if ( 'auto' !== $existing_fetchpriority ) {
		if ( $increase_count ) {
			wp_increase_content_media_count();
		} elseif ( $maybe_increase_count ) {
			/** This filter is documented in wp-includes/media.php */
			$wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 );

			if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) {
				wp_increase_content_media_count();
			}
		}
	}

	/**
	 * Filters the loading optimization attributes.
	 *
	 * @since 6.4.0
	 *
	 * @param array  $loading_attrs The loading optimization attributes.
	 * @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 apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
}
```

## История изменений

- 7.0.0 — Support fetchpriority=low and fetchpriority=auto so that loading=lazy is not added and the media count is not increased.
- 6.3.0 — Introduced.

## Связанные

Использует: [`wp_maybe_add_fetchpriority_high_attr`](https://chugunov.pro/api-wordpress/functions/wp_maybe_add_fetchpriority_high_attr/), [`wp_increase_content_media_count`](https://chugunov.pro/api-wordpress/functions/wp_increase_content_media_count/), [`wp_omit_loading_attr_threshold`](https://chugunov.pro/api-wordpress/functions/wp_omit_loading_attr_threshold/), [`wp_lazy_loading_enabled`](https://chugunov.pro/api-wordpress/functions/wp_lazy_loading_enabled/), `WP_Query::is_main_query`, [`in_the_loop`](https://chugunov.pro/api-wordpress/functions/in_the_loop/), [`is_main_query`](https://chugunov.pro/api-wordpress/functions/is_main_query/), [`doing_filter`](https://chugunov.pro/api-wordpress/functions/doing_filter/), [`did_action`](https://chugunov.pro/api-wordpress/functions/did_action/), [`__`](https://chugunov.pro/api-wordpress/functions/__/), [`is_admin`](https://chugunov.pro/api-wordpress/functions/is_admin/), [`_doing_it_wrong`](https://chugunov.pro/api-wordpress/functions/_doing_it_wrong/), [`apply_filters`](https://chugunov.pro/api-wordpress/functions/apply_filters/).
Используется в: [`wp_img_tag_add_loading_optimization_attrs`](https://chugunov.pro/api-wordpress/functions/wp_img_tag_add_loading_optimization_attrs/), [`wp_iframe_tag_add_loading_attr`](https://chugunov.pro/api-wordpress/functions/wp_iframe_tag_add_loading_attr/), `WP_Widget_Media_Image::render_media`, [`get_header_image_tag`](https://chugunov.pro/api-wordpress/functions/get_header_image_tag/), [`get_avatar`](https://chugunov.pro/api-wordpress/functions/get_avatar/), [`wp_get_attachment_image`](https://chugunov.pro/api-wordpress/functions/wp_get_attachment_image/).

Оригинал в официальной документации: https://developer.wordpress.org/reference/functions/wp_get_loading_optimization_attributes/
