How to Defer Parsing of JavaScript in WordPress
<p>PageSpeed says defer parsing of JavaScript and most WordPress sites do it wrong. Four methods, common regressions, and the INP-era reason it matters more.</p>
“Defer parsing of JavaScript” is the PageSpeed warning everyone has seen and almost no one fixes correctly in WordPress. The current version of the fix is not one button. It is a set of decisions about which scripts ship eagerly, which load late, and which should not be on the page at all.
- Top pick: WP Rocket for sites with budget, FlyingPress for builders who want sharper deferral logic, both with one-click defer and proper exclusion handling.
- Free pick: the
deferattribute via ascript_loader_tagfilter, or the free version of Autoptimize for non-developers. - What changed: Core Web Vitals replaced FID with INP. Deferring JS no longer just helps LCP. It directly moves the INP needle, and INP is the metric that fails most WordPress sites.
- Skip: async on jQuery, defer on inline scripts, “minify and combine” toggles that bundle critical and deferrable scripts together. They cause the bugs that get blamed on the plugin.
- The real win is removing scripts that should not be there, not deferring the ones that should. Audit first, defer second.
The “Defer parsing of JavaScript” warning shows upPageSpeed Insights, GTmetrix, and Lighthouse for almost every WordPress site that has more than a contact form on it. Builders who flip the toggle in their cache plugin and ship the change usually break something. A slider that needs jQuery to render, a form that posts before the validator loads, a tracking pixel that fires after the user has already left. The fix is not the toggle. The fix is knowing which scripts belong in which loading bucket and configuring the plugin accordingly.
01What “defer parsing of JavaScript” actually means
Browsers parse and execute JavaScript synchronously by default. A <script src="..."> tag in the <head> blocks the parser, blocks rendering, and pushes back the moment the page becomes interactive. Two HTML attributes change this behavior. MDN’s reference on script attributes documents both.
| Attribute | Download | Execution | Order preserved? | Use |
|---|---|---|---|---|
| (none) | Blocking | Immediate, blocks parser | Yes | Critical inline-dependent scripts only |
async | Non-blocking | As soon as it arrives, anywhere | No | Independent third-party scripts (analytics) |
defer | Non-blocking | After HTML parses, before DOMContentLoaded | Yes | Most WordPress scripts that depend on jQuery / DOM |
For WordPress, defer is almost always the right answer. Most plugin scripts depend on the DOM being parsed and on jQuery being loaded first; async breaks that ordering. Reserve async for genuinely independent scripts like analytics pixels and tag managers that are designed to run in any order.
02Why this matters more: INP replaced FID
Interaction to Next Paint (INP) replaced First Input Delay (FID) as a Core Web Vital on March 12,. The threshold for “good” INP is under 200ms. Long-running JavaScript event handlers and heavy scripts running during interaction now show up as INP failures even on sites that scored green on FID. Deferring non-critical JavaScript keeps the main thread free during interaction, which is exactly what INP measures.
We see the pattern repeatedly: WordPress sites that passed Core Web Vitals on FID before 2024 fail INP after the rollout because their themes and plugins enqueue JavaScript that runs during scroll, hover, and click events. Deferring is a partial fix; removing unused scripts is the bigger one.
03Method 1: WP Rocket (paid, the cleanest deferral)
If you have a budget for one performance plugin, this is it. The “Load JavaScript Deferred” toggle and the per-script “Delay JavaScript Execution” list are the cleanest controls in the WordPress ecosystem.
Buy if: the site earns money and you cannot afford an afternoon debugging defer ordering. Skip if: the site is hobby-scale and the free plugins below cover you.
WP Rocket at a glance
- Pricing
- From around $59/year for one site
- Defer JS
- Single toggle plus per-script exclusion list
- Delay JS execution
- Yes, with first-interaction trigger (great for INP)
- Critical CSS
- Generated automatically per template
- Best
- Sites with budget that need defaults that work
Settings → File Optimization → JavaScript: enable “Load JavaScript Deferred” and “Delay JavaScript Execution”. The exclusion list ships with sensible defaults for jQuery, popular analytics, and recaptcha. If you run a tag manager or a chat widget, add it to “Excluded JavaScript Files” by URL fragment.
04Method 2: FlyingPress (paid, our pick for builders)
FlyingPress’s “Defer JavaScript” implementation is more aggressive and surfaces fewer regressions on themes with complex script dependencies. The interaction-trigger feature is what we use on production sites.
Buy if: you want the best INP outcome from a single plugin. Skip if: the existing WP Rocket license already works for the site.
FlyingPress separates “Defer” from “Delay” cleanly. Defer applies the HTML defer attribute. Delay holds the script until first user interaction (mouse move, scroll, touch). For most marketing sites, delay is the option that moves INP. Use defer for first-party scripts, delay for third-party scripts, and exclude critical scripts (header navigation, lazy-load library) from both.
05Method 3: Autoptimize (free, decent for non-developers)
The free option that produces decent results on most themes. The “Aggregate JS files” option is the bug factory. Leave it off.
Buy if: the site is hobby-scale and the budget is zero. Skip if: the site has a complex theme or many plugins; the free option produces more regressions than the paid alternatives.
Settings → Autoptimize → JS: enable “Optimize JavaScript Code”. Leave “Aggregate JS files” disabled. It bundles all scripts into one file, which breaks dependencies on most themes and is rarely a win on HTTP/2 hosts where requests are cheap. Add critical scripts (theme jQuery, navigation library) to the “Exclude scripts from Autoptimize” field.
06Method 4: A code-only fix in functions.php (free, surgical)
For developers who already have a child theme. Adds defer via the script_loader_tag filter without a plugin. Best when you need control over which scripts are excluded.
Buy if: the site is custom-built and you want zero plugin overhead. Skip if: non-developers will edit the site and you need a UI.
The WordPress filter for adding attributes to a <script> tag is script_loader_tag. Drop the snippet below into the child theme’s functions.php or a code-snippets plugin:
add_filter('script_loader_tag', function ($tag, $handle) {
// Scripts to NEVER defer (depend on inline init, render-critical, etc.)
$skip = ['jquery-core', 'jquery-migrate', 'wp-i18n'];
if (in_array($handle, $skip, true)) {
return $tag;
}
// Add defer to every other enqueued script
if (strpos($tag, ' defer ') === false) {
$tag = str_replace(' src=', ' defer src=', $tag);
}
return $tag;
}, 10, 2);
The $skip array is the surgical part. Add a script’s handle (the first argument to wp_enqueue_script) to the list when deferring breaks it. Read the page source to find handles, or use the Query Monitor plugin to list every enqueued script with its handle and source.
07The pre-defer audit: scripts that should not be on the page
Before deferring anything, audit what is loaded. Open Chrome DevTools → Network tab, filter by JS, and reload the page. The list shows every script the page requests. Half of what you see on a typical WordPress site is removable, not just deferrable.
Defer these
- Sliders, carousels, modals
- Comment-form scripts
- Theme animation libraries
- Lazy-loading scripts (after first paint)
- Most plugin frontend scripts
Remove these instead
- Plugin scripts loaded site-wide for one page (use
wp_dequeue_script) - Old jQuery UI or Migrate scripts WordPress no longer needs
- Tracking pixels for tools you do not use
- Embedded scripts from removed widgets
- Block library JS on pages that use no blocks
The cheapest performance win on most WordPress sites is conditionally dequeuing scripts that should not load on every page. Contact Form 7’s frontend script does not need to be on the homepage. WooCommerce’s cart script does not need to be on the blog. The Perfmatters plugin exposes a “Script Manager” that handles this without code, or wp_dequeue_script() handles it from a child theme.
08Which method should you pick?
Pick the right deferral approach
- Production site, money on the line, INP failing? → WP Rocket or FlyingPress with delay-on-interaction
- Hobby site, budget zero? → Autoptimize with “Optimize JS” only, leave aggregation off
- Custom-built theme, developer maintaining it? →
script_loader_tagfilter in functions.php - One specific script breaks after deferring? → Add it to the exclusion list and move on
- INP still failing after deferring? → Audit unused scripts; deferring will not help if the script does not need to be on the page
09Common defer regressions and how to spot them
DOMContentLoaded.
<script> tags assuming $() is ready immediately fail when jQuery is deferred. Either upgrade the plugin or exclude jquery-core from defer.
10FAQ
Should I use async or defer for WordPress JavaScript?
Defer for almost every script. Most WordPress scripts depend on jQuery and the DOM being ready in order; async breaks that ordering. Reserve async for genuinely independent third-party scripts like analytics that are designed to run in any order.
Will deferring JavaScript break my WordPress site?
It can break sliders, carousels, comment forms, and any script that uses inline initialization. The fix is to add the script to the plugin’s exclusion list. Test on staging first.
Does deferring JavaScript improve Core Web Vitals?
Yes, especially INP since the March 2024 rollout. Deferring keeps the main thread free during interaction, which is exactly what INP measures. It also helps LCP indirectly when render-blocking scripts in the head are pushed below the parser.
Is WP Rocket worth it just for the defer feature?
For a site that earns money, yes. The exclusion-list defaults plus the delay-on-interaction option produce a measurable INP win without the regressions that come with free plugin defaults. For hobby sites, the free options below are enough.
What is the difference between defer and delay?
Defer applies the HTML defer attribute, which holds execution until after HTML parses but before DOMContentLoaded. Delay holds execution until first user interaction (scroll, click, touch). Delay produces better INP scores but can break scripts that need to run before interaction.
11WikiWalls verdict
WikiWalls verdict. WP Rocket or FlyingPress for production sites with budget. Autoptimize for hobby sites with no budget. The
script_loader_tagfilter for custom themes maintained by developers. The bigger win is removing scripts that should not be on the page; defer the rest. Test on staging. Defer regressions are easier to fix than to explain.
This guide was last reviewed and updated by WikiWalls recently to reflect Core Web Vitals INP measurement, current plugin pricing, and the current ecosystem of WordPress performance plugins.
Discussion · 2
Real names, real fixes. We moderate for clarity, not opinion.
Comments are closed.
hi..how are u?
This solution not work for me….it stop the juery functionality on some pages….lease give me solution for this.Thanks in advance.