Attributes for Resource Hints in 4.7

WordPress 4.6 added support for Resource Hints, a W3C specification that “defines the dns-prefetch, preconnect, prefetch, and prerender relationships of the HTML Link Element (<link>)”. These can be used to assist the browser in the decision process of which origins it should connect to, and which resources it should fetch and preprocess to improve page performance.

With WordPress 4.7, you’re now able to pass specific HTML attributes to these resource hints to make even better use of them. Namely, the as, crossorigin, pr, and type attributes can now be defined when using the wp_resource_hints filter. See #38121 for more information.

Here’s an example of how one can use this new feature:

function makewp_example_resource_hints_attributes( $hints, $relation_type ) {
	if ( 'prefetch' === $relation_type ) {
		$hints[] = array(
			'crossorigin' => 'use-credentials',
			'as'          => 'style',
			'pr'          => 0.5,
			'href'        => 'https://example.com/foo.css',
		);
	}

	return $hints;
}

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

While crossorigin can be used to set the CORS settings for a resource, pr indicates the expected probability that the specified resource hint will be used. The official W3C specification has more information about these attributes.

Note: preload is not yet supported by wp_resource_hints(), mainly because of a lack of browser support and benefit for core. This will continue to be reevaluated as browser support evolves for these emerging features.

#4-7, #dev-notes, #script-loader

Introducing admin_print_footer_scripts-$hook_suffix in 4.6

The admin_print_footer_scripts action hook is the last chance to localize admin scripts; but it is a generic one. If you ever wanted to do something for specific admin pages only, you would either have to hook into another dynamic action, or hook into admin_print_footer_scripts and check the $hook_suffix (which is not even passed, but that’s not an issue) yourself. The problem with the former is that there might be happening a lot between the chosen action and when your script gets enqueued (admin_print_footer_scripts); and maybe you need to be aware of what has happened. The problem with the latter is that you would have to register possibly a lot of functions, maybe check the current admin page inside several of these, and eventually bail most of the times. That’s why WordPress 4.6 brings the dynamic footer action admin_print_footer_scripts-$hook_suffix. See [37279].

The following pre-4.6 code

add_action( 'admin_print_footer_scripts', function() {
    global $hook_suffix;

    if ( 'some_admin_page' !== $hook_suffix ) {
        return;
    }

    // Whatever it is that you want to do...
} );

can now be simplified like this:

add_action( 'admin_print_footer_scripts-some_admin_page', function() {
    // Whatever it is that you want to do...
} );

This change brings more consistency between wp-admin/admin-footer.php and wp-admin/admin-header.php, which already fires the generic admin_print_scripts and the dynamic admin_print_scripts-$hook_suffix actions.

For more background on the change, see #34334.

#4-6, #dev-notes, #plugins, #script-loader

Resource Hints in 4.6

Resource Hints is a rather new W3C specification that “defines the dns-prefetch, preconnect, prefetch, and prerender relationships of the HTML Link Element (<link>)”. These can be used to assist the browser in the decision process of which origins it should connect to, and which resources it should fetch and preprocess to improve page performance.

Introduced with [37920], WordPress now has a simple API to register and use resource hints. The relevant ticket is #34292

By default, wp_resource_hints() prints hints for s.w.org (the WordPress.org CDN) and for all scripts and styles which are enqueued from external hosts.

Developers can use the wp_resource_hints filter to add custom domains and URLs for dns-prefetch, preconnectprefetch or prerender. One needs to be careful to not add too many resource hints as they could quite easily negatively impact performance, especially on mobile, but the filter works like this:

function makewp_example_resource_hints( $hints, $relation_type ) {
	if ( 'dns-prefetch' === $relation_type ) {
		$hints[] = '//make.wordpress.org';
	} else if ( 'prerender' === $relation_type ) {
		$hints[] = 'https://make.wordpress.org/great-again';
	}

	return $hints;
}

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

#4-6, #dev-notes, #script-loader

Enhanced Script Loader in WordPress 4.5

This post summarizes some of the changes to the script loader and script/style dependencies in WordPress 4.5.

Individual stylesheets instead of wp-admin.min.css

Ticket: #35229

Currently, WordPress generates and ships relatively large 235KB wp-admin.min.css and wp-admin-rtl.min.css files which are created from source files which we also ship.
With WordPress 4.5 we stop generating these files and instead rely upon load-styles.php to combine them. This removes the requirement from shipping for commits such as [35896] 510KB of CSS. Instead, we only have to ship the 4 dashboard.css files which are around 72KB.

For plugin authors nothing should change because the script loader takes care of the new dependency for the wp-admin handle. Also, wp-admin.* files are still generated for compatibility purposes, however, they only include the @import() lines.

Breaking Change: If your plugin or theme is still using the deprecated media functionality please note that in [36869] the style handle was changed from media to media-deprecated.

HTTP ETag header for load-scripts.php and load-styles.php

Ticket: #28722

Both loaders for script and style concatenation are now sending an ETag header which includes the value of $wp_version. This improves performance since browsers won’t re-download the scripts and styles when they send the HTTP_IF_NONE_MATCH header and there was no change in $wp_version. ⚡️

wp_add_inline_script()

Ticket: #14853

For quite some time wp_add_inline_style() has been available to add extra CSS styles to a registered stylesheet. Now there’s an equivalent function to do the same for inline JavaScript. wp_add_inline_script() can be used to add extra scripts either before or after a registered script using the optional third $position argument.

For example, the following code can be used to easily add Typekit’s JavaScript to your theme:

function mytheme_enqueue_typekit() {
   wp_enqueue_script( 'mytheme-typekit', 'https://use.typekit.net/<typekit-id>.js', array(), '1.0' );
   wp_add_inline_script( 'mytheme-typekit', 'try{Typekit.load({ async: true });}catch(e){}' );
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_typekit' );

Which results in:

<script type='text/javascript' src='https://use.typekit.net/<typekit-id>.js?ver=1.0'></script>
<script type='text/javascript'>
try{Typekit.load({ async: true });}catch(e){}
</script>

Scripts/Styles with “alias” handles

Ticket: #35643, #25247, #35229

Alias handles are handles without a $src parameter. Those can be used to group dependencies, like core is doing for jQuery[36550] changes how those handles are loaded, more specifically, they are no longer skipped early in WP_Dependencies.

Now, inline styles and scripts attached to alias handles will do something important — get printed out. This change was required by the switch to an alias handle for wp-admin to provide backwards compatibility for plugins which are adding inline styles to the wp-admin handle.

Support for scripts with dependencies in different groups

Ticket: #35873, #35873

Scripts can be registered in two groups: head or footer. Previously, dependencies of registered scripts were moved to the header, even when the script that depends on them is loaded in the footer. This was fixed in [36871]. The changeset includes some expressive tests to demonstrate how complex dependencies, like “grandchild” dependencies, can be enqueued.

Last, but not least, WP_Dependencies, WP_Styles, and WP_Scripts are now fully documented. 📘

Thanks to @abiralneupane, @atimmer, @dd32, @gitlost, @ocean90, @sebastian.pisula, @sergej.mueller, @stephenharris, and @swissspidy for their contributions!

#4-5, #dev-notes, #script-loader