wp_resource_hints()WP 4.6.0

Prints resource hints to browsers for pre-fetching, pre-rendering and pre-connecting to web sites.

Gives hints to browsers to prefetch specific pages or render them in the background, to perform DNS lookups or to begin the connection handshake (DNS, TCP, TLS) in the background.

These performance improving indicators work by using <link rel"…">.

1 time — 0.000474 sec (fast) | 50000 times — 7.01 sec (fast) | PHP 7.4.25, WP 6.0
Hooks from the function

Return

null. Nothing.

Usage

wp_resource_hints();

Examples

0

#1 How to properly disable DNS prefetch for s.w.org (emoji)

Since version 4.6.0 there is a special hook that allows you to disable prefetch for s.w.org (emoji):

// Removing DNS prefetch for WP Emoji from the header
add_filter( 'emoji_svg_url', '__return_false' );
0

#2 Add prefetch instructions for custom URLs (domains)

Suppose we need to forcibly add browser instructions for certain URLs or domains. Let's use hook wp_resource_hints:

add_filter( 'wp_resource_hints', 'wp_kama_resource_hints_filter', 10, 2 );

/**
 * Function for `wp_resource_hints` filter-hook.
 *
 * @param array  $urls          Array of resources and their attributes, or URLs to print for resource hints.
 * @param string $relation_type The relation type the URLs are printed for, e.g. 'preconnect' or 'prerender'.
 *
 * @return array
 */
function wp_kama_resource_hints_filter( $urls, $relation_type ){

	if( 'dns-prefetch' === $relation_type ){
		$urls[] = 'https://dnsprefetch.com/foo';
	}

	if( 'preconnect' === $relation_type ){
		$urls[] = 'https://preconnect.com/some';
	}

	if( 'prefetch' === $relation_type ){
		$urls[] = 'https://prefetch.com/some';
		$urls[] = '//prefetch-no-proto.com/some';
		$urls[] = [
			'href'        => 'https://prerender-array.com/some.css',
			'as'          => 'style',
			'crossorigin' => 'use-credentials',
			'pr'          => 12.5,
			'type'        => 'text/css',
		];
	}

	if( 'prerender' === $relation_type ){
		$urls[] = 'https://prerender.com/some';
	}

	return $urls;
}

Get the following in the HEAD part of the HTML:

<link rel='dns-prefetch' href='//dnsprefetch.com' />

<link rel='preconnect' href='https://preconnect.com' />

<link rel='prefetch' href='https://prefetch.com/some' />
<link rel='prefetch' href='//prefetch-no-proto.com/some' />
<link href='https://prerender-array.com/some.css' as='style' crossorigin='use-credentials' pr='12.5' type='text/css' rel='prefetch' />

<link rel='prerender' href='https://prerender.com/some' />
0

#3 Removing dns-prefetch rule from HTML HEAD

Suppose we have dns-prefetch rules in the HTML document <head> which we don't need and we need to remove them. For example, we need to delete the following domain external.com:

add_filter( 'wp_resource_hints', function( $urls ) {

	foreach ( $urls as $key => $url ) {

		if ( str_contains( $url, 'external.com' ) ) {
			unset( $urls[ $key ] );
		}
	}

	return $urls;
} );

Changelog

Since 4.6.0 Introduced.

wp_resource_hints() code WP 6.1.1

function wp_resource_hints() {
	$hints = array(
		'dns-prefetch' => wp_dependencies_unique_hosts(),
		'preconnect'   => array(),
		'prefetch'     => array(),
		'prerender'    => array(),
	);

	foreach ( $hints as $relation_type => $urls ) {
		$unique_urls = array();

		/**
		 * Filters domains and URLs for resource hints of relation type.
		 *
		 * @since 4.6.0
		 * @since 4.7.0 The `$urls` parameter accepts arrays of specific HTML attributes
		 *              as its child elements.
		 *
		 * @param array  $urls {
		 *     Array of resources and their attributes, or URLs to print for resource hints.
		 *
		 *     @type array|string ...$0 {
		 *         Array of resource attributes, or a URL string.
		 *
		 *         @type string $href        URL to include in resource hints. Required.
		 *         @type string $as          How the browser should treat the resource
		 *                                   (`script`, `style`, `image`, `document`, etc).
		 *         @type string $crossorigin Indicates the CORS policy of the specified resource.
		 *         @type float  $pr          Expected probability that the resource hint will be used.
		 *         @type string $type        Type of the resource (`text/html`, `text/css`, etc).
		 *     }
		 * }
		 * @param string $relation_type The relation type the URLs are printed for,
		 *                              e.g. 'preconnect' or 'prerender'.
		 */
		$urls = apply_filters( 'wp_resource_hints', $urls, $relation_type );

		foreach ( $urls as $key => $url ) {
			$atts = array();

			if ( is_array( $url ) ) {
				if ( isset( $url['href'] ) ) {
					$atts = $url;
					$url  = $url['href'];
				} else {
					continue;
				}
			}

			$url = esc_url( $url, array( 'http', 'https' ) );

			if ( ! $url ) {
				continue;
			}

			if ( isset( $unique_urls[ $url ] ) ) {
				continue;
			}

			if ( in_array( $relation_type, array( 'preconnect', 'dns-prefetch' ), true ) ) {
				$parsed = wp_parse_url( $url );

				if ( empty( $parsed['host'] ) ) {
					continue;
				}

				if ( 'preconnect' === $relation_type && ! empty( $parsed['scheme'] ) ) {
					$url = $parsed['scheme'] . '://' . $parsed['host'];
				} else {
					// Use protocol-relative URLs for dns-prefetch or if scheme is missing.
					$url = '//' . $parsed['host'];
				}
			}

			$atts['rel']  = $relation_type;
			$atts['href'] = $url;

			$unique_urls[ $url ] = $atts;
		}

		foreach ( $unique_urls as $atts ) {
			$html = '';

			foreach ( $atts as $attr => $value ) {
				if ( ! is_scalar( $value )
					|| ( ! in_array( $attr, array( 'as', 'crossorigin', 'href', 'pr', 'rel', 'type' ), true ) && ! is_numeric( $attr ) )
				) {

					continue;
				}

				$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );

				if ( ! is_string( $attr ) ) {
					$html .= " $value";
				} else {
					$html .= " $attr='$value'";
				}
			}

			$html = trim( $html );

			echo "<link $html />\n";
		}
	}
}