0

I'm looking for a way to automatically add defer to all JS files on my server. While I found a way that seem to be working, I am not sure if this is the best way / best practice 2021 for WordPress?

I am running a test environment on XAMPP with PHP 7.4.x and the latest WordPress (5.7.2). I have debug turned on in wp-config and while I am not receiving any errors or notices, I am again, not sure this is the best way / best practice to do this.

Can someone please review and advise?

I am using this code:

add_filter( 'clean_url', 'auto_defer_all_js_and_jquery', 11, 1 );
function auto_defer_all_js_and_jquery( $url ) {

    if ( false === strpos($url, '.js') ) {

        return $url;
    }

    if ( !false === strpos($url, '.js') ) {

        return "$url' defer='defer";
    }
}
2
  • 1
    If you have scripts that depend on other scripts, like jQuery, and they’re not built to handle loading asynchronously, you’re likely going to break a lot of things. If adding async was a magic bullet for solving performance without breaking anything then the browser would do it automatically. Commented Jun 12, 2021 at 7:49
  • Okay, good point. So you're saying that adding an array of exceptions would be the best way forward? Could you please elaborate on the hook used and if that's the way to go? Commented Jun 12, 2021 at 8:14

1 Answer 1

2

Here's a solution to your question. This doesn't take into account the merit of whether or not you should add async or defer to certain assets, it just gives you the tools to do it yourself, or not.

Points to note:

  • this is only for use with Javascript includes (obviously)
  • It's not 100% accurate because of the method of replacing the tag text, but for 99.9% of the javascript includes you'll have, it'll do the job the fine.
  • there is the option to specify which includes should have the async and defer tags, simply add the handles of the assets you want to apply it to. I've included JQuery for starters.
  • this code add both defer="defer" and async. Simply delete either of the appropriate if blocks if that's not what you want.
function add_async_to_js( $includeTag, $handle ) {

    $handlesToChange = [
        'jquery'
    ];

    if ( in_array( $handle, $handlesToChange ) ) {
        if ( strpos( $includeTag, ' defer=' ) === false ) {
            $includeTag = str_replace( ' src=', ' defer="defer" src=', $includeTag );
        }
        if ( strpos( $includeTag, ' async' ) === false ) {
            $includeTag = str_replace( ' src=', ' async src=', $includeTag );
        }
    }
    return $includeTag;
}

add_filter( 'script_loader_tag', 'add_async_to_js', 10, 2 );
3
  • TIL about script_loader_tag - neato :)
    – bosco
    Commented Jun 12, 2021 at 16:14
  • Very nice. Thank you. It's a great starting point and you taught me something. I appreciate it. Commented Jun 13, 2021 at 6:26
  • No problem at all, glad it helps you out!
    – Paul G.
    Commented Jun 13, 2021 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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