What is the difference between defer and async on a <script> tag?

Both download scripts without blocking HTML parsing. defer runs after parsing in document order; async runs immediately when downloaded, in any order.

HTMLJavaScript

Overview

By default, a `<script>` tag in the `<head>` blocks HTML parsing until the script downloads and executes - slowing page load. `defer` and `async` both allow non-blocking downloads, but differ in when the script runs.

Key Points

  • •Normal `<script>` in `<head>`: blocks parsing. Avoid for large scripts.
  • •`defer`: downloads in parallel, executes after the HTML is fully parsed, in document order.
  • •`async`: downloads in parallel, executes immediately when ready (may interrupt parsing), in no guaranteed order.
  • •Both attributes only work for external scripts (`src="..."`) they are ignored on inline scripts.
  • •Use `defer` for scripts that depend on the DOM or on each other. Use `async` for truly independent scripts (analytics, ads).

Examples

Normal script (blocking)

html
<!-- Parsing stops until script.js downloads + runs -->
<head>
  <script src="script.js"></script>
</head>

defer: execute after parsing, in order

html
<head>
  <script defer src="utils.js"></script>   <!-- runs first -->
  <script defer src="app.js"></script>     <!-- runs second, after utils.js -->
</head>
<!-- Both download in parallel while HTML parses -->
<!-- Both execute in order after </html> is reached -->

Equivalent to placing scripts just before </body>, but cleaner in <head>.

async: execute as soon as downloaded

html
<head>
  <!-- Whichever downloads first, runs first - order not guaranteed -->
  <script async src="analytics.js"></script>
  <script async src="ads.js"></script>
</head>

Great for independent third-party scripts that do not depend on the DOM or each other.

Side-by-side comparison

text
             | Download  | When executed        | Order guaranteed
-------------|-----------|----------------------|------------------
<script>     | Blocking  | Immediately          | Yes (blocks)
defer        | Parallel  | After HTML parsed    | Yes
async        | Parallel  | When download done   | No

Pro Tip

For your own application scripts, almost always use `defer`. It guarantees the DOM is ready and scripts run in the correct order. Only use `async` for self-contained third-party tags like Google Analytics that do not interact with your DOM or other scripts.