Deferring JavaScript loading can help the browser process HTML faster and display the main page content sooner. The defer attribute is commonly used for this purpose because it postpones script execution until the HTML document has been parsed.
However, adding defer or async to every file without analysis is risky. Some scripts are required for menus, forms, carts, checkout, analytics, or other plugin features. If the execution order changes, the site may lose interactivity or display errors in the browser console.
What defer Does and How It Differs from async
A standard JavaScript file in the head can pause HTML parsing: the browser downloads and executes the file, then continues building the page. The defer attribute allows the file to download in parallel with HTML processing but delays execution until the document has been parsed.
For standard external scripts, defer preserves the execution order in which the scripts are included. This makes it more predictable for files with dependencies. async works differently: the script executes as soon as it finishes downloading, so the order may change depending on network speed.
For this reason, async is suitable only for independent scripts that do not depend on jQuery, libraries, or other code. For scripts with dependencies, defer is safer to consider, or you can leave the default loading behavior in place.
- defer: downloads in parallel with HTML and executes after HTML parsing is complete;
- async: executes immediately after downloading, without guaranteeing the overall execution order;
- standard loading: the most predictable option, but it can block page processing.
Which Scripts Can Be Deferred
Start by analyzing the role of each JavaScript file rather than by applying the defer attribute. Good candidates are scripts that are not needed for the initial page rendering, such as catalog filters, additional modal windows, interactive blocks below the first screen, or features that run only after a user action.
Do not automatically defer jQuery, the theme’s main script, page builder files, cart and checkout scripts, or libraries that other files depend on. A file may be critical on one page even if it is not used on another.
Check inline code separately as well. It may expect a particular library to be available when it executes. Adding defer to an external file without analyzing related inline scripts often creates errors that are not visible from the list of loaded files alone.
- Safer candidates: independent widgets, filters, sliders, and features that are not needed immediately.
- Riskier candidates: jQuery, its plugins, theme scripts, WooCommerce scripts, and page builder files.
- Do not combine defer for a library with async for a file that depends on it without testing.
How to Identify a Script Handle in WordPress
In WordPress, scripts are loaded using a handle, which is a unique identifier such as catalog-filter or theme-script. This is the handle you pass to wp_script_add_data(), not the file URL or the name of the JavaScript file on disk.
You can find the handle in the theme or plugin code, inside the wp_enqueue_script() call. The Network tab in DevTools and the page source can also help: the handle is often included in the name or ID of the generated script tag, although checking the script registration in the code is more reliable.
Also review the dependencies specified during registration. If catalog-filter depends on jQuery or another library, deferring it must account for that dependency. The handle must already be registered or enqueued through wp_enqueue_script() before its attributes are changed.
- Look for the third parameter of wp_enqueue_script(), where dependencies are often defined.
- Check which pages actually load the handle.
- Do not change every script according to one universal rule without checking the relevant templates.
Example of Selectively Adding defer
In the example below, the defer strategy is added only to the catalog-filter script and only on pages that use the templates/catalog.php template. The priority of 100 gives the theme or plugin time to register the required handle.
This code does not register the script itself. If the handle does not exist, WordPress cannot apply the strategy to it. First confirm that the script is loaded on the required page.
- Replace catalog-filter with the actual handle of your script.
- Replace templates/catalog.php with the actual template path.
- Do not add async to the same script if it has dependencies.
add_action('wp_enqueue_scripts', function () {
if (!is_page_template('templates/catalog.php')) {
return;
}
wp_script_add_data(
'catalog-filter',
'strategy',
'defer'
);
}, 100);
How to Test the Site After Making Changes
Test more than loading speed. Check every scenario that may depend on the modified script. Testing only the homepage will not reveal issues that occur in the catalog, customer account area, or checkout.
After clearing the cache, open the site in an incognito window and test pages on both mobile and desktop devices. If caching or a CDN is used, confirm that visitors are receiving the updated HTML and JavaScript.
- Console: check for errors such as is not defined, Cannot read properties of undefined, and file-loading errors.
- Network: confirm that required scripts load, do not return 404 or blocked statuses, and execute in the expected order.
- Interface: test the mobile menu, search, filters, sliders, tabs, and modal windows.
- Forms and WooCommerce: add a product to the cart, change the quantity, apply a coupon, proceed to checkout, and submit a test form.
- Performance: compare the metrics while also confirming that page stability and user interaction have not deteriorated.
Common JavaScript Optimization Mistakes
The most common mistake is adding defer or async globally to every script through an optimization plugin or a filter in functions.php. This approach may provide a short-term improvement to one metric but break features that are used only on specific templates.
Another issue is changing attributes without accounting for caching. An old combined or minified file may remain cached by the optimization plugin, CDN, or browser, meaning the test results will not reflect the new configuration.
You should also avoid trying to fix errors simply by switching from defer to async. If the cause is an incorrect dependency, duplicate loading, or a plugin conflict, changing the strategy only makes the behavior less predictable.
- Do not edit plugin or theme files directly because updates will overwrite your changes.
- Do not defer a script simply because it is large: first identify its dependencies and role.
- Do not treat the absence of errors on the homepage as proof that checkout or forms work correctly.
- After making changes, clear caches in the correct order: site, server, CDN, and browser, depending on your infrastructure.
Frequently asked questions
Can you add defer to jQuery in WordPress?
Technically, yes, but its safety depends on every script that uses jQuery. If other files or inline code expect jQuery to be available earlier, errors may occur. Without analyzing dependencies, it is better not to defer it globally.
When should you use async?
async is appropriate for independent scripts whose execution order does not matter, such as certain external services or trackers. It is risky for libraries and plugins with dependencies.
Why does wp_script_add_data() not change the script tag?
The most common reasons are that the handle is not registered, the script is not loaded on that page, or the code runs before the script is registered. Check the handle, the template condition, and the hook priority.
Is defer alone enough to improve Core Web Vitals?
No. Defer can reduce blocking during HTML processing, but the result also depends on the amount of JavaScript, styles, images, the server, and other resources. Evaluate changes as a whole and do not sacrifice functionality.
Conclusion
Deferring JavaScript in WordPress works best as a targeted optimization. First identify which handle is not needed for the initial render, check its dependencies, and limit the change to a specific template or page type.
Use defer carefully, do not apply async to dependent scripts, and always test the console, navigation, forms, and WooCommerce. Deferring one safe file is better than globally changing the execution order of every script and ending up with a broken site.