Difference Between Async and Defer in JavaScript

When building modern websites, loading JavaScript efficiently is essential for optimal page speed and user experience. By default, script tags block the HTML parser, causing delays in rendering content. The async and defer attributes are boolean attributes added to <script> tags to download external scripts asynchronously in the background. This article explains how normal script execution works, breaks down the core mechanics of async and defer, compares their differences, and guides you on when to use each.

Default Script Loading (Without Attributes)

When a browser encounters a standard <script src="..."> tag without any attributes:

  1. HTML parsing is immediately paused.
  2. The browser downloads the script over the network.
  3. The browser executes the script completely.
  4. HTML parsing resumes only after execution finishes.

This render-blocking behavior slows down the First Contentful Paint (FCP) and degrades performance.


The async Attribute

The async (asynchronous) attribute tells the browser to download the script in the background while continuing to parse the HTML document. However, as soon as the script finishes downloading, HTML parsing is paused to execute the script immediately.

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

Key characteristics of async: * Non-blocking download: HTML parsing continues while the file downloads. * Immediate execution: Parsing pauses as soon as the file arrives so the script can execute. * Independent order: If you have multiple async scripts, they execute in the order they finish downloading, not the order they appear in the HTML.


The defer Attribute

The defer (deferred) attribute also downloads the script in the background without interrupting HTML parsing. Unlike async, deferred scripts will not execute until the entire HTML document has been fully parsed, just before the DOMContentLoaded event fires.

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

Key characteristics of defer: * Non-blocking download and parsing: HTML parsing is never interrupted by the download or execution. * Executes after DOM is ready: Scripts run only after the DOM tree is completely built. * Preserves order: Multiple defer scripts execute in the exact order they appear in the source code.


Comparison of Script Loading Methods

Feature Default <script> <script async> <script defer>
HTML Parsing During Download Blocked Non-blocking Non-blocking
HTML Parsing During Execution Blocked Blocked Non-blocking (Runs after parsing)
Execution Timing Immediately after download Immediately after download After complete DOM parsing
Execution Order Sequential (as defined) Non-sequential (load order) Sequential (as defined)

When to Use async vs defer

Use async when: * The script is completely independent and does not rely on other scripts. * The script does not depend on or manipulate the DOM structure directly. * Examples: Google Analytics, tracking pixels, ad network scripts, and telemetry tools.

Use defer when: * The script interacts with or modifies DOM elements. * The script depends on other scripts (or other scripts depend on it), requiring a guaranteed execution order. * Examples: UI frameworks, event listeners, main application bundles, and jQuery plugins.