Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save westonruter/9694840a1cb940e66bdfb650e34c325e to your computer and use it in GitHub Desktop.
Save westonruter/9694840a1cb940e66bdfb650e34c325e to your computer and use it in GitHub Desktop.
Use async/defer in a backwards compatible manner
<?php
/**
* Register scripts with a `defer` or `async` strategy in a backwards compatible manner.
*
* From WordPress 6.3 onwards, the `wp_register_script` function accepts an `$args` array that
* can include a `strategy` key with a value of either `async` or `defer`.
*
* This helper function handles the backwards compatibility for older versions of WordPress. When a
* `strategy` key is present in the `$args` array (and is either `defer` or `async`), the
* `script_loader_tag` filter is used to add the attribute to the script tag. Note that
* for older versions of WordPress, dependency is not managed and the attribute is added unconditionally.
*
* When support for WP<6.3 is no longer required, simply replace all instances of this function with
* `wp_register_script()`.
*
* @see wp_register_script()
*
* @param string $handle Name of the script. Should be unique.
* @param string|false $src Full URL of the script, or path of the script relative to the WordPress root directory.
* If source is set to false, script is an alias of other scripts it depends on.
* @param string[] $deps Optional. An array of registered script handles this script depends on. Default empty array.
* @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL
* as a query string for cache busting purposes. If version is set to false, a version
* number is automatically added equal to current installed WordPress version.
* If set to null, no version is added.
* @param array|bool $args {
* Optional. An array of additional script loading strategies. Default empty array.
* Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false.
*
* @type string $strategy Optional. If provided, may be either 'defer' or 'async'.
* @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'.
* }
* @return bool Whether the script has been registered. True on success, false on failure.
*/
function wpnext_register_script( $handle, $src, $deps, $ver, $args ) {
// If >= 6.3, re-use wrapper function signature.
if ( version_compare( strtok( get_bloginfo( 'version' ), '-' ), '6.3', '>=' ) ) {
wp_register_script(
$handle,
$src,
$deps,
$ver,
$args
);
} else {
wp_register_script(
$handle,
$src,
$deps,
$ver,
isset( $args['in_footer'] ) ? $args['in_footer'] : false
);
if ( isset( $args['strategy'] ) ) {
wp_script_add_data( $handle, 'strategy', $args['strategy'] );
}
}
}
/**
* Enqueue scripts with a `defer` or `async` strategy in a backwards compatible manner.
*
* From WordPress 6.3 onwards, the `wp_enqueue_script` function accepts an `$args` array that
* can include a `strategy` key with a value of either `async` or `defer`.
*
* This helper function handles the backwards compatibility for older versions of WordPress. When a
* `strategy` key is present in the `$args` array (and is either `defer` or `async`), the
* `script_loader_tag` filter is used to add the attribute to the script tag. Note that
* for older versions of WordPress, dependency is not managed and the attribute is added unconditionally.
*
* When support for WP<6.3 is no longer required, simply replace all instances of this function with
* `wp_enqueue_script()`.
*
* @see wp_enqueue_script()
*
* @param string $handle Name of the script. Should be unique.
* @param string $src Full URL of the script, or path of the script relative to the WordPress root directory.
* Default empty.
* @param string[] $deps Optional. An array of registered script handles this script depends on. Default empty array.
* @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL
* as a query string for cache busting purposes. If version is set to false, a version
* number is automatically added equal to current installed WordPress version.
* If set to null, no version is added.
* @param array|bool $args {
* Optional. An array of additional script loading strategies. Default empty array.
* Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false.
*
* @type string $strategy Optional. If provided, may be either 'defer' or 'async'.
* @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'.
* }
*/
function wpnext_enqueue_script( $handle, $src, $deps, $ver, $args ) {
wpnext_register_script( $handle, $src, $deps, $ver, $args );
wp_enqueue_script( $handle );
}
if ( version_compare( get_bloginfo( 'version' ), '6.3', '<' ) ) {
add_filter(
'script_loader_tag',
static function( $tag, $handle ) {
$strategy = wp_scripts()->get_data( $handle, 'strategy' );
if ( in_array( $strategy, array( 'async', 'defer' ), true ) ) {
$p = new WP_HTML_Tag_Processor( $tag );
if ( $p->next_tag( 'script' ) ) {
$p->set_attribute( $strategy, true );
$tag = $p->get_updated_html();
}
}
return $tag;
},
10,
2
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment