Async vs Defer Script Attributes: How They Affect HTML Parsing and Execution

The async attribute downloads scripts in parallel with HTML parsing and executes them immediately when ready, potentially before parsing completes, while defer also downloads in parallel but delays execution until after the entire document is parsed and before the DOMContentLoaded event fires.

Understanding the distinction between async and defer script attributes is essential for optimizing web page performance and controlling JavaScript execution timing. These attributes, documented in the h5bp/Front-end-Developer-Interview-Questions repository within src/questions/html-questions.md, determine how browsers handle external script resources relative to HTML document parsing. Both attributes modify the default blocking behavior of script tags, but they differ significantly in execution timing and order guarantees.

Default Script Loading Behavior

Without any attributes, a standard <script src="..."> tag forces the browser to halt HTML parsing until the script is downloaded, parsed, and executed. This synchronous blocking can delay page rendering and create performance bottlenecks, particularly for large scripts or slow network connections.

The Async Attribute

The async attribute enables parallel downloading of script resources while the browser continues parsing the HTML document.

Download and execution timing: Execution begins as soon as the download completes, regardless of whether the HTML parser has finished processing the remaining document. This means async scripts can run at any point during parsing, potentially interrupting the construction of the DOM.

Execution order: Multiple async scripts do not guarantee execution order—each runs immediately upon availability. This behavior makes the attribute suitable for independent, non-dependent resources such as analytics trackers or advertisement scripts.

The Defer Attribute

The defer attribute similarly allows parallel downloading, but delays execution until the HTML document is fully parsed.

Execution timing: Deferred scripts run after the entire HTML document has been parsed and just before the DOMContentLoaded event fires. This ensures the complete DOM is available before script execution begins.

Order preservation: Unlike async, multiple defer scripts maintain their execution order according to their position in the markup. This characteristic makes defer ideal for scripts that depend on each other or require access to the complete DOM structure.

Critical Differences Between Async and Defer

Both attributes only function with external scripts that include a src attribute—inline scripts ignore these attributes entirely. The key distinctions include:

  • Blocking behavior: async pauses HTML parsing only briefly during script execution, while defer allows uninterrupted parsing throughout the entire document loading process.

  • Execution sequence: async executes immediately upon download completion without guaranteeing order; defer waits for parsing to finish and preserves markup sequence.

  • Use cases: async is appropriate for standalone utilities like analytics, whereas defer supports dependent scripts that rely on DOM readiness.

Practical Implementation Examples

According to the source code analysis in src/questions/html-questions.md from the h5bp repository, here is how to implement these attributes:

<!-- Async: runs immediately when loaded, order not guaranteed -->
<script src="analytics.js" async></script>

<!-- Defer: runs after DOM is ready, preserves execution order -->
<script src="app.js" defer></script>
<script src="utils.js" defer></script>

In this example, analytics.js may execute at any time during or after parsing, while app.js and utils.js will always execute after the DOM is fully constructed, with app.js running before utils.js due to their markup order.

Summary

  • Both async and defer enable parallel script downloading without blocking HTML parsing during the download phase.

  • async executes scripts immediately upon download completion without guaranteeing execution order.

  • defer delays execution until after HTML parsing completes and maintains the original markup order for multiple scripts.

  • Neither attribute affects inline scripts—only external scripts with src attributes respond to these modifiers.

  • Choose async for independent resources like tracking codes; use defer for scripts requiring DOM readiness or specific execution sequences.

Frequently Asked Questions

Do async and defer attributes work with inline JavaScript?

No, both async and defer attributes are ignored for inline scripts lacking a src attribute. According to the h5bp/Front-end-Developer-Interview-Questions source, these attributes are only effective for external scripts.

Which attribute maintains script execution order?

The defer attribute preserves execution order among multiple scripts, running them sequentially in the order they appear in the markup. In contrast, async scripts execute as soon as they load without any guarantee of sequence.

When exactly do deferred scripts execute relative to DOMContentLoaded?

Deferred scripts execute after the entire HTML document has been parsed but just before the DOMContentLoaded event fires. This timing ensures the DOM is fully constructed while allowing scripts to initialize before event listeners trigger.

What happens if a script tag has neither async nor defer attributes?

Without either attribute, the script blocks HTML parsing until it is fetched, parsed, and executed. This synchronous behavior can delay page rendering and should be avoided for performance-critical applications.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →