Javascript is an integral part of Front-end development and heavily used in modern web development. It’s used to develop modern web sites and web apps. This makes JavaScript a cornerstone to modern Web Development. WordPress adds JS functionality using the wp_enqueue_script action hook. You can add a JS file in a theme or plugin using this hook. By default, WordPress loads all files synchronously at the top in <head>
tag. This can be render blocking messing up Core Web Vitals and leading to lower efficiency. This could affect SEO performance of website. Fortunately, we can load JS asynchronously not blocking the render of our website. In this article, we are going to see how to load JavaScript asynchronously in WordPress. While there are many cache plugins that can do it but here we are going to take a look at how to do it without plugin. There are a couple of ways which we are going to discuss further. But before diving into the how, we need to know exactly what is asynchronous loading and how does it help make site load faster.
This article expects that you have good understanding of WordPeress Development and understand working of hooks and actions.
What is asynchronous loading?
Asynchronous loading refers to the condition where JavaScript files are loaded along with the DOM and parsed either after files are loaded completely (async) or after DOM has loaded (defer). This can help reduce loading times of websites as Javascript files are usually quite bulky and resource intensive leading to higher load times. To load scripts asynchronously, we utlize 2 attributes provided in JS – async
and defer
. Let’s see what is the difference between these two tags.
With async tag, the files are loaded along with the DOM and executed as soon as they are loaded.
With defer tag, the files loaded along with the DOM and loaded once DOM parsing has finished.
There are essentially 2 prominent ways through which we could load JavaScript files asynchronously in WordPress. Let’s get to it!
How to load JavaScript asynchronously in WordPress
Using script_loader_tag
The most frequent and popular method used to add JS files asynchronously is the script_loader_tag
filter. The function hooked to this filter accepts 3 arguments: $tag – the complete <script> tag of the script being loaded, $handle – the unique handle of the added script and $src – the JavaScript file’s source URL. Through this filter, we basically have access to the <script> tag ($tag) used to enqueue the JS file using wp_enqueue_script and can modify it as per our requirement. We can target a specific tag using either $handle or $src. Consider the following example –
1 2 3 4 5 6 7 8 9 |
function my_theme_modify_script( $tag, $handle, $src ) { if ($handle == 'my-script-handle') { $tag = str_replace('<script ', '<script defer ', $tag); } return $tag; } add_filter('script_loader_tag', 'my_theme_modify_script', 10, 3); |
The code is pretty self-explanatory. Here, we do a simple search and replace using PHP’s str_replace
function. This filter hook is executed just before scripts are loaded but tags are created. In the above code, we defer the script to get executed at the end after parsing the DOM. We can add the async
tag in a similar manner –
1 2 3 4 5 6 7 8 9 |
function my_theme_modify_script( $tag, $handle, $src ) { if ($handle == 'my-script-handle') { $tag = str_replace('<script ', '<script async ', $tag); } return $tag; } add_filter('script_loader_tag', 'my_theme_modify_script', 10, 3); |
Using wp_enqueue_script
As of WordPress 6.3, WordPress is providing the capability to load scripts asynchronously (either defer
or async
) in the wp_enqueue_script function itself which is used to load JS files in WordPress. The final parameter $args
accepts an array with keys strategy
and in_footer
. The strategy
key accepts defer and async as values. defer defers the script loading it with the DOM but executing when DOM has loaded. async loads the script asynchronously (non-blocking) and executes the script as soon as it’s loaded. The second key in_footer when set true, loads the script in footer instead of the <head>
tag. Consider the following code –
1 2 3 4 5 6 7 8 9 10 |
$url = get_template_directory_uri() . '/js/functions.js'; $time = filemtime( get_template_directory() . '/js/functions.js' ); $args = array( 'in_footer' => true, 'strategy' => 'defer', ); wp_enqueue_script( 'wpdocs-functions', $url, array(), $time, $args ); |
I took this snippet directly from the codex and shows how to defer a script loading it in footer.
Please keep in mind that while loading scripts asynchronously is a neat feature and helps tremendously in optimizing websites, it needs to be used with prudence as in some cases, scripts are required while loading the DOM and need to be loaded synchronously.
So that was it! In this article, we load javascript asynchronously using two ways the script_loader_tag
WordPress filter hook and wp_enqueue_script
function.In both the methods, we can either async or defer the code. I hope you got to learn something new here. I post more gems and aha! moments of WordPress on my blog. Do check it out.
One thought on “How to load JavaScript asynchronously (defer / async) in WordPress”