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:
- HTML parsing is immediately paused.
- The browser downloads the script over the network.
- The browser executes the script completely.
- 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.