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!

有帮助吗?

解决方案 2

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 );

其他提示

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().

许可以下: CC-BY-SA归因
scroll top