async vs defer Attributes for script Elements

written by idriss douiri profile picture Idriss Douiri

2 min read

async and defer script attributes.
share

Both async and defer attributes are used to fetch scripts asynchronously without blocking the HTML parser, but what is the difference between them? And when to use each.

About async and defer

  • Both require the src attribute and only work for external scripts.
  • async overrides defer if both exist on the same script.
  • Scripts with type="module" are deferred by default.
  • Scripts created by document.createElement('script') are async by default.
  • async and defer are ignored in inline scripts with no src.

Scripts with no defer / async

To better understand the difference between async and defer, let’s first examine what happens when we don’t set any of them.

  1. The browser fetches the HTML.
  2. It starts parsing the HTML to form the DOM.
  3. It finds the script element.
  4. The parser is blocked until the script is loaded and executed.

A timeline chart showing HTML parsing pausing while the script is downloaded and executed, then resuming afterward.

This means the script doesn’t know about the elements under it, therefore it can’t interact with them.

Additionally, loading large scripts at the top of your HTML can slow down your website resulting in a blank screen.

A simple and ineffective solution is placing the script at the bottom of the page.

Scripts with async

When adding the async attribute to a script element, the same process is followed as before. But this time, the script loads on a separate thread in parallel to parsing HTML, and once the fetching is done, its execution blocks the parser.

A timeline chart where HTML parsing and script downloading happen in parallel, but execution pauses parsing once the script is ready.

The execution order of multiple async scripts is not guaranteed, as each script will execute as soon as it is fetched.

Scripts with defer

Similar to async, deferred scripts will load in the background without blocking the parsing process, but they will only execute after the parsing is done.

A timeline chart showing HTML parsing and script downloading happening simultaneously, with script execution occurring only after parsing is complete.

This means deferred scripts won’t block the HTML parser and can interact with other elements even if they come after the script.


<script defer src="script.js"></script>

<p class="name"></p> <!-- the script can access this paragraph -->

Also, deferred scripts will execute in the order they are declared in.

When to use defer vs async?

  • Use just <script> for small inline scripts to set global settings.
  • Use async for independent scripts like analytics.
  • Use defer for scripts that manipulate the DOM or depend on other scripts.