0

At https://core.trac.wordpress.org/changeset/37920 it defines the wp_resource_hints() function that was added with WordPress 4.6.

On that page it shows a section of the general-template.php file where the wp_resource_hints() function is defined, and there's also a function called wp_resource_hints_scripts_styles() which "Adds dns-prefetch for all scripts and styles enqueued from external hosts."

I would like to replace "dns-prefetch" with "preconnect" for all external enqueued scripts and styles. In other words, I would like the wp_resource_hints_scripts_styles() function to use "preconnect" somehow.

Is there a way I can modify the wp_resource_hints() function to achieve this?

I'm looking at the following part of the function, where "dns-prefetch" points to wp_resource_hints_scripts_styles(), and I'm wondering if that can be changed to use "preconnect" instead:

$hints = array(
  'dns-prefetch' => wp_resource_hints_scripts_styles(),
  'preconnect'   => array( 's.w.org' ),
  'prefetch'     => array(),
  'prerender'    => array(),
);

Apologies if I haven't worded this question in the clearest way!

0

There's a filter, wp_resource_hints, but it only filters each "relation type" (i.e. preconnect, dns-prefetch, etc.) individually, rather than the whole $hints array in your question. However, you could use the filter to empty the array for dns-prefetch and add wp_resource_hints_scripts_styles() to the preconnect array, like this:

add_filter(
    'wp_resource_hints',
    function( $urls, $relation_type ) {
        if ( 'dns-prefetch' === $relation_type ) {
            $urls = [];
        }

        if ( 'preconnect' === $relation_type ) {
            $urls = wp_dependencies_unique_hosts();
        }

        return $urls;
    },
    0,
    2
);

Note that I used a priority of 0. This is to make sure that any URLs that were manually added to dns-prefetch by another plugin or theme aren't accidentally removed from all the lists, since we're only able to move the URLs from wp_dependencies_unique_hosts().

  • Thanks so much - it's perfect, and nice and simple too! Works a treat. – GermanKiwi Aug 21 '19 at 20:46
  • Hi @jacob-peattie, I just noticed something odd with the function you provided here. Before using your function, my dns-prefetch links used protocol-relative URLs, like this: <link rel='dns-prefetch' href='//fonts.googleapis.com' /> But after enabling your function, the new preconnect links have 'http:' prepended to them - even though my site uses HTTPS: <link rel='preconnect' href='http://fonts.googleapis.com' /> Any idea why, or how I can prevent this from happening with your function? I'd prefer to the preconnect links to use HTTPS or at least protocol-relative URLs. – GermanKiwi Nov 2 '19 at 16:45
0

I finally figured out how to get this to work correctly, and also including the correct scheme (http or https) with each 'preconnect' link.

I made a copy of the wp_dependencies_unique_hosts() function (part of WordPress core) and modified it so it output both the scheme and host, and then incorporated it into the function that @jacob-peattie provided in his answer here. The resulting function works perfectly - as follows. (I go into further details about it here: Change dns-prefetch to preconnect with correct protocol)

function dns_prefetch_to_preconnect( $urls, $relation_type ) {
    global $wp_scripts, $wp_styles;

    $unique_urls = array();

    foreach ( array( $wp_scripts, $wp_styles ) as $dependencies ) {
        if ( $dependencies instanceof WP_Dependencies && ! empty( $dependencies->queue ) ) {
            foreach ( $dependencies->queue as $handle ) {
                if ( ! isset( $dependencies->registered[ $handle ] ) ) {
                    continue;
                }

                $dependency = $dependencies->registered[ $handle ];
                $parsed     = wp_parse_url( $dependency->src );

                if ( ! empty( $parsed['host'] ) && ! in_array( $parsed['host'], $unique_urls ) && $parsed['host'] !== $_SERVER['SERVER_NAME'] ) {
                    $unique_urls[] = $parsed['scheme'] . '://' . $parsed['host'];
                }
            }
        }
    }

    if ( 'dns-prefetch' === $relation_type ) {
        $urls = [];
    }

    if ( 'preconnect' === $relation_type ) {
        $urls = $unique_urls;
    }

    return $urls;
}
add_filter( 'wp_resource_hints', 'dns_prefetch_to_preconnect', 0, 2 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.