JavaScript 3 min read

defer vs async: Loading JavaScript the Right Way

How you load a script can matter as much as its size. Learn the difference between normal, async, defer and module scripts, and which to use for themes, analytics and third-party widgets.

On this page

Key takeaways

  • A plain <script src> in the head blocks HTML parsing until it downloads and runs.
  • defer downloads in parallel and runs after parsing, in order — the best default for your own scripts.
  • async downloads in parallel and runs as soon as it’s ready, in any order — good for independent scripts like analytics.

“Eliminate render-blocking resources” is one of the most common PageSpeed Insights warnings on WordPress sites. Often the fix is a single attribute on a script tag. Understanding the difference between defer and async lets you apply it safely.

What happens with a normal script#

<head>
  <script src="/slider.js"></script>
</head>

The browser stops parsing HTML, downloads slider.js, executes it, and only then continues. On a slow mobile connection, that can delay everything visible by a second or more.

The three loading modes#

Normal async defer
Blocks HTML parsing while downloading? Yes No No
When does it run? Immediately As soon as downloaded (may interrupt parsing) After HTML is fully parsed, before DOMContentLoaded
Execution order preserved? Yes No Yes
Can access full DOM? Only elements above it Not guaranteed Yes
Best for Rare: tiny inline scripts that must run first (e.g. theme flash prevention) Independent scripts: analytics, ads Site scripts, libraries with dependencies

Examples#

<!-- Your site code: depends on the DOM and on each other -->
<script src="/vendor/library.js" defer></script>
<script src="/main.js" defer></script>

<!-- Independent third-party analytics -->
<script src="https://www.googletagmanager.com/gtag/js?id=G-XXXX" async></script>

<!-- ES modules are deferred by default -->
<script type="module" src="/app.js"></script>

Exceptions: when blocking is correct#

A tiny inline script that must run before the page paints — like the one that applies dark mode to avoid a white flash — should stay inline and blocking at the top of the head. Keep such scripts to a few lines.

Need a hand with this?

Get a quick, honest review of your website’s SEO.

Chat on WhatsApp

Beyond defer: delaying third-party scripts#

Even deferred scripts compete for CPU right after load, affecting INP. For non-essential tags (chat widgets, heatmaps, social embeds), load them after the first user interaction or when the browser is idle:

<script>
function loadChat() {
  var s = document.createElement('script');
  s.src = 'https://chat.example.com/widget.js';
  s.async = true;
  document.body.appendChild(s);
}
['scroll', 'pointerdown', 'keydown'].forEach(function (e) {
  addEventListener(e, loadChat, { once: true, passive: true });
});
</script>

See third-party scripts for a full strategy.

In WordPress#

Since WordPress 6.3, themes and plugins can register scripts with a loading strategy:

wp_enqueue_script( 'my-main', get_template_directory_uri() . '/main.js', array(), '1.0', array( 'strategy' => 'defer', 'in_footer' => true ) );

This theme loads all of its scripts with defer. For plugins that don’t, performance plugins (WP Rocket, LiteSpeed Cache, Perfmatters, FlyingPress) can add defer or delay scripts — always test menus, forms, sliders and checkout afterwards, and exclude scripts that break.

Common mistakes#

  • Adding async to jQuery and plugins that depend on it — they may run before jQuery and fail.
  • Using defer on inline scripts (it only works on external scripts with src).
  • Delaying scripts needed for above-the-fold content, causing visible pop-in.
  • Moving everything to the footer but still blocking — footer scripts without defer still block the end of parsing.

defer vs async FAQ#

Should I put scripts in the head or before </body>?#

With defer, put them in the head so downloads start early. Without it, placing them before </body> was the old workaround.

Can I use both defer and async?#

If both are present, modern browsers use async. Choose one.

Does defer improve SEO?#

Indirectly — faster rendering improves Core Web Vitals and user experience.

Found this useful? Share it

Join the discussion

Your email address will not be published. Required fields are marked *

Security code image. If you cannot read it, press refresh or contact me on WhatsApp.