Skip to content
Dev Craftdefer Issue #969

How to Defer Parsing of JavaScript in WordPress

What to know

<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>


⚡ TLDR

“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 defer attribute via a script_loader_tag filter, 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.

AttributeDownloadExecutionOrder preserved?Use
(none)BlockingImmediate, blocks parserYesCritical inline-dependent scripts only
asyncNon-blockingAs soon as it arrives, anywhereNoIndependent third-party scripts (analytics)
deferNon-blockingAfter HTML parses, before DOMContentLoadedYesMost 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)

WikiWalls verdict 9.1 / 10

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)

WikiWalls verdict 9.0 / 10

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)

WikiWalls verdict 7.6 / 10

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)

WikiWalls verdict 8.0 / 10

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

  1. Production site, money on the line, INP failing? → WP Rocket or FlyingPress with delay-on-interaction
  2. Hobby site, budget zero? → Autoptimize with “Optimize JS” only, leave aggregation off
  3. Custom-built theme, developer maintaining it?script_loader_tag filter in functions.php
  4. One specific script breaks after deferring? → Add it to the exclusion list and move on
  5. 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

The slider stops working. Sliders typically depend on inline initialization scripts. Inline scripts cannot be deferred. The fix is to exclude the slider library from defer and the inline init runs as expected.
Forms submit before validation runs. Validation libraries deferred too aggressively miss their bind to the form’s submit event. Either move validation to a non-deferred bundle or initialize on DOMContentLoaded.
jQuery breaks for plugins that expect it synchronously. Older plugins that use inline <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_tag filter 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.


Administrator · 28 published guides · Joined 2016

Welcome to wikiwalls

Discussion · 2

Real names, real fixes. We moderate for clarity, not opinion.

  1. This solution not work for me….it stop the juery functionality on some pages….lease give me solution for this.Thanks in advance.

Comments are closed.

The WikiWalls Journal · Free, weekly

One careful fix in your inbox each Wednesday.

No affiliate links inside the diagnosis. No sponsored "top 10". One careful fix per week — unsubscribe in one click.

No tracking pixels · No spam · Edited by a human.