On WordPress 6.3 and later, defer a script by passing 'strategy' => 'defer' in the $args array of wp_enqueue_script(). If a script is already registered, use wp_script_add_data( $handle, 'strategy', 'defer' ). Defer lets the browser parse the HTML without waiting for that file, then executes the file after parsing while preserving dependency order.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
Use this for scripts you control and have tested. Do not blindly defer jQuery, inline-dependent code, or third-party scripts that other code expects to run immediately. Also check whether a caching or optimization plugin is adding its own defer processing, because applying both systems can change execution behavior.
As an Amazon Associate I earn from qualifying purchases.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallHow to defer JavaScript WordPress: what the setting changes
A normal script in the document head can be render-blocking: the browser pauses HTML parsing while it downloads and executes the file. That pause delays the point at which the page can be displayed and interacted with.
A script printed with the HTML defer attribute downloads while the document is being parsed. It executes after parsing has finished, before the browser’s DOMContentLoaded event, and deferred scripts execute in document order. WordPress’s script loader uses the dependency graph to keep that order where the graph is complete.
#1 Best Overall
Defer is different from moving a script to the footer. A footer script is placed later in the document, while a deferred head script can begin downloading earlier without blocking the parser. You can use both: WordPress’s developer reference requires a strategy-bearing script either to be printed in the footer or to use a deferred strategy so module import maps are printed before evaluation.
Defer is also different from async. An asynchronous script executes as soon as it finishes downloading, so its execution order is not guaranteed relative to other asynchronous files. That makes async useful for independent code, but risky for libraries and scripts with dependencies.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesWordPress defer JavaScript with the 6.3+ API
WordPress 6.3 added native async and defer support to the script functions. No filter hack is required on supported versions.
Pattern A: pass the strategy while enqueuing
Use the sixth argument of wp_enqueue_script() for a script that you register and enqueue in one call:
<?php
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_script(
'my-app',
get_stylesheet_directory_uri() . '/js/app.js',
array(),
'1.0.0',
array(
'in_footer' => true,
'strategy' => 'defer',
)
);
} );
The handle is my-app; the URL points to the theme’s js/app.js; the version string supports cache invalidation; in_footer => true prints the tag in the footer; and strategy => 'defer' adds the deferred loading strategy. Keep the version value aligned with your actual release process rather than leaving a stale value in production.
If you prefer a head tag so downloading starts earlier, set in_footer to false and retain strategy => 'defer'. Test module-based code and import maps carefully, because the footer-or-deferred requirement exists to preserve their evaluation order.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Pattern B: add defer after registration
Use wp_script_add_data() when another function or plugin has already registered the handle, or when you want to set the strategy separately:
Rank #2
<?php
add_action( 'wp_enqueue_scripts', function () {
wp_register_script(
'my-app',
get_stylesheet_directory_uri() . '/js/app.js',
array(),
'1.0.0',
true
);
wp_enqueue_script( 'my-app' );
wp_script_add_data( 'my-app', 'strategy', 'defer' );
} );
This pattern registers the file in the footer with the final argument set to true, enqueues it, then attaches the strategy to the registered handle. WordPress 6.3 understands the strategy data. Older WordPress versions ignore that data, so the script remains a normal script instead of producing a defer attribute or a fatal error.
Choosing the right hook and handle
Theme front-end files normally belong in wp_enqueue_scripts. Administration screens use admin_enqueue_scripts, and block-editor assets may have different loading requirements. Add strategy data to the exact registered handle, not to the filename or URL. If a plugin registers vendor-library and your code registers vendor-library again, you may be modifying a different registration than the one that is printed.
Defer versus async: which strategy fits a script?
| Property | defer |
async |
|---|---|---|
| HTML parsing while downloading | Continues | Continues |
| Execution timing | After document parsing | As soon as downloading finishes |
| Order among scripts using the same strategy | Preserved in document order | Not guaranteed |
| Typical use | Application bundles and dependency chains | Independent analytics or widgets |
| Main risk | Code that expects to run before parsing completes | Race conditions with libraries, inline code, or other files |
For a theme bundle that depends on a library, start with defer. Consider async only when the file is genuinely independent and its completion order cannot affect page behavior. WordPress accepts either value in the strategy field, but the browser semantics remain different.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Dependency rules you must preserve
WordPress calculates a strategy that is compatible with the dependency graph; it cannot make an unsafe chain safe merely because one handle is marked deferred. The practical rule is:
- A script using
defermay depend on scripts that are blocking or also deferred. - Every dependent script that relies on that deferred file must itself be deferred, otherwise it may execute before its dependency.
- Do not mark a library deferred while leaving an inline or external consumer that expects the library synchronously available.
For example, if app depends on core-lib, enqueue both with a compatible strategy:
<?php
wp_enqueue_script(
'core-lib',
get_stylesheet_directory_uri() . '/js/core-lib.js',
array(),
'2.4.0',
array( 'in_footer' => true, 'strategy' => 'defer' )
);
wp_enqueue_script(
'app',
get_stylesheet_directory_uri() . '/js/app.js',
array( 'core-lib' ),
'1.8.0',
array( 'in_footer' => true, 'strategy' => 'defer' )
);
If app has no dependency declaration, WordPress cannot infer that relationship. Declare dependencies in the third argument instead of relying on the order in which PHP functions happen to run.
When not to defer a script
jQuery and early inline code
Keep jQuery and similar foundational libraries out of the deferred set unless you have tested every consumer. Deferred files wait until parsing is complete. Inline code in the head, an inline configuration block, or a plugin’s initialization routine may run earlier and fail with an undefined function or object.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Do not defer a handle merely because it appears in the page source. Trace its dependents, search for inline calls such as jQuery(...) or window.SomeLibrary, and test pages that use the feature. A blocking library plus a deferred application bundle can be valid; a deferred library plus blocking consumers is usually not.
Scripts that modify document parsing
Code that uses document.write(), must run before a particular markup block is parsed, or injects a critical polyfill may need to remain blocking. Replace those patterns where possible, but do not defer them as a blind performance fix.
Third-party tags
Third-party handles are harder to reason about because you may not control their inline bootstrap code, network response, or update schedule. Defer a third-party script only after confirming its documented loading requirements and checking the provider’s current integration instructions.
How to force JavaScript async/defer in WordPress safely
A blanket rule that adds async or defer to every script is more likely to break a site than to improve it. Use a handle allowlist and make each exclusion explicit.
- List the printed handles. Inspect the page source and the browser’s Network and Initiator panels. Record theme, plugin, inline, and third-party files separately.
- Map dependencies. Check each
wp_enqueue_script()call, especially the dependency array. Identify which files provide globals used by other files. - Start with theme-owned bundles. Add
strategy => 'defer'to application and component bundles that initialize after the DOM is available. - Exclude fragile handles. Keep jQuery, early polyfills, and scripts with undocumented inline consumers unchanged until tested.
- Propagate the strategy through consumers. If a deferred library has dependents, make the dependent chain deferred too, or leave the library blocking.
- Test every template that enqueues the handle. Check the front page, singular posts, archives, search, forms, menus, authenticated views, and any page-builder templates.
- Remove overlapping automation. Disable a plugin’s JavaScript deferral feature temporarily while testing core strategies, then choose one system as the source of truth.
For a handle already registered by a plugin, a targeted approach looks like this:
<?php
add_action( 'wp_enqueue_scripts', function () {
if ( wp_script_is( 'site-widget', 'registered' ) ) {
wp_script_add_data( 'site-widget', 'strategy', 'defer' );
}
} );
Use a handle that is actually registered on the page. This does not make an unregistered file appear, and it does not override a script that another system later rewrites.
Render-blocking JavaScript WordPress: what defer can and cannot fix
Defer removes parser blocking for the selected external scripts, but it does not make the files free. They still consume bandwidth, connection slots, CPU time, and main-thread execution time. A large bundle can still delay interactivity after it begins executing.
Rank #4
Defer also does not replace code splitting, removing unused modules, compressing assets, or postponing nonessential features until user interaction. Those are separate optimizations. Treat the strategy as a loading-order decision, not a guaranteed speed score.
No publisher-attributed performance percentage is established for this API. The effect depends on the number and size of scripts, the dependency graph, device, network, caching, and how much work each script performs after parsing. Measure before and after on representative templates rather than promising a fixed improvement.
Plugin optimization conflicts and double processing
Caching and optimization plugins may add their own defer or delay behavior. A plugin can rewrite a tag that WordPress has already marked with a strategy, add a second attribute, change execution to a queue, or move inline code. A support report documented a conflict between a plugin’s deferral and WordPress strategy attributes; the general lesson is to avoid two independent systems controlling the same handles.
When diagnosing a conflict:
- Clear page caches, object caches, CDN caches, and minification caches after each configuration change.
- Temporarily disable the optimization plugin’s JavaScript defer/delay option and test the native WordPress strategy alone.
- View the final HTML delivered to the browser, not only the PHP enqueue call.
- Re-enable one feature at a time and compare the resulting attributes, order, and inline bootstrap code.
Compatibility with older WordPress versions
The $args array form with strategy is intended for WordPress 6.3 and newer. On older installations, use a version check if the same code must run across a mixed fleet, or accept that the strategy will not be applied there.
<?php
add_action( 'wp_enqueue_scripts', function () {
$args = array( 'in_footer' => true );
if ( version_compare( get_bloginfo( 'version' ), '6.3', '>=' ) ) {
$args['strategy'] = 'defer';
}
wp_enqueue_script(
'my-app',
get_stylesheet_directory_uri() . '/js/app.js',
array(),
'1.0.0',
$args
);
} );
wp_script_add_data( $handle, 'strategy', 'defer' ) is understood by WordPress 6.3 and ignored by older versions. Ignoring the data means the older site receives its normal script behavior; it does not create a defer attribute there.
Free tools Windows power users keep installed
One-click scans. No signup required.
Maintain the version check only when you truly support pre-6.3 sites. If your minimum supported version is already 6.3, the direct strategy argument is simpler and easier to audit.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Testing and troubleshooting deferred scripts
The browser reports an undefined function
Identify which file defines the missing function and which file calls it. If the caller is blocking while the provider is deferred, align their strategies or keep the provider blocking. Also search for inline scripts that run before the deferred file.
Best Value
A menu, form, or slider works only after refresh
Check whether the initialization code depends on a DOM-ready event, a global created by another script, or an inline configuration object. Ensure the dependency is declared and that all consumers use a compatible strategy. Test with browser caching disabled and with a logged-out session as well as an authenticated one.
The strategy attribute is absent
Confirm the handle is the one printed, that the code runs before scripts are printed, and that the site runs WordPress 6.3 or newer. Inspect the final response after cache purges. A plugin or theme may deregister and re-register the handle, or an optimization layer may replace the tag.
Recommended Free Tools
Module code fails with an import-map error
Review where the script is printed. The WordPress developer-reference caveat requires a strategy-bearing script to be in the footer or deferred so the module import map is output before the script evaluates. Do not force an asynchronous strategy onto a module chain that relies on import-map ordering.
Only one template breaks
Compare the handles and inline data on the working and failing templates. Conditional enqueues often mean a dependency exists only on a checkout, form, account, or page-builder route. Fix the conditional dependency declaration rather than removing defer site-wide.
How to verify that WordPress defer JavaScript is working
- Open the rendered page source and locate the script handle’s tag.
- Confirm the tag contains a deferred strategy in the final HTML, or that it is printed in the footer as intended.
- In browser developer tools, inspect the Network request and the Initiator chain to verify the expected file order.
- Use the Console with cache disabled to catch early initialization errors.
- Exercise interactive features before and after scrolling, navigation, form submission, and viewport changes.
- Repeat the check after cache and CDN purges, because stale HTML can hide a configuration change.
Test on a representative mobile device or throttled connection as well as a fast desktop. A strategy that appears harmless on a fast development machine can expose a race condition on a slower one.
Deployment checklist
- WordPress is 6.3 or newer, or your code deliberately handles older versions.
- The strategy is attached to the correct registered handle.
- Dependencies and dependents have compatible strategies.
- jQuery and other early libraries were excluded or explicitly tested.
- Footer placement and module import-map ordering are valid.
- Theme-owned bundles are separated from third-party scripts during evaluation.
- Only one caching or optimization layer controls defer/delay behavior.
- All important templates and logged-in states were tested after cache purges.
- The final HTML, not just PHP source, contains the behavior you intended.
What changed in WordPress after 6.3?
The native strategy API was introduced in WordPress 6.3. The available status information does not establish a later 2026 core change that replaces this API. A proposal in the plugin ecosystem discusses native defer behavior together with fetchpriority, but that is not a WordPress core feature and should not be treated as one. For current sites, use the documented strategy argument or wp_script_add_data(), then verify the generated markup and execution order.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




