Make WordPress Core

Opened 4 years ago

Last modified 3 years ago

#52465 new enhancement

Allow a relation type in resource hints to be used multiple times

Reported by: geekpress's profile GeekPress Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: Script Loader Keywords: has-patch has-unit-tests needs-dev-note
Focuses: Cc:

Description

wp_resource_hints function restricts to one time the usage of a relation type for a resource hint.

This can be a problem for preconnect which can be used with and without crossorigin attribute at the same time for performance reason.

As an example, a CDN should have two preconnect like this:

<link href='//mycdn.test' rel='preconnect' />
<link href='//mycdn.test' rel='preconnect' crossorigin />

Please check this post as reference:
https://crenshaw.dev/preconnect-resource-hint-crossorigin-attribute/#:~:text=Summary,be%20downloaded%20from%20that%20origin.&text=If%20CORS%20won't%20be,two%20resource%20hints%20are%20necessary

I attached a patch which will allow to use multiple times a resource with different configurations. This patch also avoid a resource to be printed multiple times if all attrs are the same.

e.g:

<?php
function preconnect_mycdn( $hints, $relation_type ) {
        $domains = [
                [
                        'href'        => '//mycdn.test/',
                ],
                [
                        'href'        => '//mycdn.test/',
                        'crossorigin' => 'use-credentials',
                ],
                [
                        'href'        => '//mycdn.test/',
                ],
                [
                        'href'        => '//mycdn.test/',
                        'crossorigin' => 'anonymous',
                ],
        ];

        foreach ( $domains as $domain ) {
                if ( 'preconnect' === $relation_type ) {
                        $hints[] = $domain;
                }
        }

        return $hints;
}
add_filter( 'wp_resource_hints', 'preconnect_mycdn', 10, 2 );

will print:

<link href='//mycdn.test' rel='preconnect' />
<link href='//mycdn.test' crossorigin='anonymous' rel='preconnect' />

Attachments (1)

52465.diff (737 bytes) - added by GeekPress 4 years ago.

Download all attachments as: .zip

Change History (8)

@GeekPress
4 years ago

This ticket was mentioned in PR #1216 on WordPress/wordpress-develop by Tabrisrp.


4 years ago
#1

  • Keywords has-patch has-unit-tests added

This change allows to have the same URL in the wp_resource_hints() array, and added to the HTML, if:

  • there is one entry using the crossorigin attribute
  • and one not using it

Example:

$urls[] = array(
	'href' => 'https://example.org',
);

$urls[] = array(
	'href'        => 'https://example.org',
	'crossorigin' => 'anonymous',
);

will output:

<link href='https://example.org' rel='preconnect' />
<link href='https://example.org' crossorigin='anonymous' rel='preconnect' />

A new unit test has been added to validate the code change. Existing tests still passes too.

Trac ticket: https://core.trac.wordpress.org/ticket/52465

#2 @tabrisrp
4 years ago

  • Keywords has-patch has-unit-tests removed

I added a PR on Github for this enhancement.

It takes a different approach because the proposed patch was causing existing unit tests to fail.

I focused on the crossorigin compatibility, as it seems it's the only attribute for which we really want the possibility to have multiple entries for the same URL.

Added an additional test case to validate the change, and the existing tests still pass too.

#3 @tabrisrp
4 years ago

  • Keywords has-patch has-unit-tests added

#4 @audrasjb
4 years ago

  • Keywords needs-dev-note added
  • Milestone changed from Awaiting Review to 5.8

Hello, thanks both for the patchs/unit tests,

I tested the pull request using the test code provided by @GeekPress:

function preconnect_mycdn( $hints, $relation_type ) {
        $domains = [
                [
                        'href'        => '//mycdn.test/',
                ],
                [
                        'href'        => '//mycdn.test/',
                        'crossorigin' => 'use-credentials',
                ],
                [
                        'href'        => '//mycdn.test/',
                ],
                [
                        'href'        => '//mycdn.test/',
                        'crossorigin' => 'anonymous',
                ],
        ];

        foreach ( $domains as $domain ) {
                if ( 'preconnect' === $relation_type ) {
                        $hints[] = $domain;
                }
        }

        return $hints;
}
add_filter( 'wp_resource_hints', 'preconnect_mycdn', 10, 2 );

Before PR 1216 is applied, this result to this single line being printed in the head section of the page:

<link href='//mycdn.test' crossorigin='anonymous' rel='preconnect' />

After applying the PR, here's the result:

<link href='//mycdn.test' rel='preconnect' />
<link href='//mycdn.test' crossorigin='anonymous' rel='preconnect' />

The PR seems to work as expected. Plus, it has unit tests. Therefore, I'm moving this for 5.8 consideration.

Also adding needs-dev-note keyword, in case the change can make it into 5.8.

Thanks all

#5 @desrosj
4 years ago

  • Milestone changed from 5.8 to 5.9

@GeekPress Thanks so much for this ticket and the PR!

Today is feature freeze date for 5.8. Since the focus has been heavily on full site editing this release, a committer has unfortunately not had the chance to review this. I'm going to punt this to the 5.9 milestone as it seems ready to go pending a thorough review.

This ticket was mentioned in Slack in #core by hellofromtonya. View the logs.


3 years ago

#7 @hellofromTonya
3 years ago

  • Milestone changed from 5.9 to Future Release

Today is 5.9 Feature Freeze. I'm sorry to say this ticket slipped through the cracks and did not get attention during the 5.9 cycle. Need to punt it. As 6.0 milestone has not yet been added for selection, it'll be moved to Future Release. Once 6.0 is available, please feel free to add it to that cycle.

Note: See TracTickets for help on using tickets.