HTML defer Attribute

Beginner
⏱️ 5 min read
📚 Updated: Jun 2026
🎯 3 Examples
Performance & Scripts

What You’ll Learn

The defer attribute is a boolean attribute on <script src="..."> elements. It tells the browser to download the script in parallel with HTML parsing, then execute it after the document has been fully parsed—without blocking page rendering. Deferred scripts run in document order, which makes defer ideal for app logic that depends on the DOM.

01

Non-Blocking

Parse HTML first.

02

External src

Requires src URL.

03

Boolean

Presence = defer.

04

Order Kept

Scripts run in sequence.

05

vs async

Compare loading.

06

JavaScript

script.defer = true.

Purpose of defer

Without defer or async, a classic script in the <head> can block HTML parsing while it downloads and runs. The defer attribute improves page load performance by letting parsing continue while the script file downloads in the background. Execution is postponed until the HTML document is fully parsed.

Because deferred scripts run in the order they appear in the document, you can safely load a library first and an app script second. Deferred scripts typically run before the DOMContentLoaded event fires.

💡
External scripts only

defer applies to <script src="..."> only. It has no effect on inline scripts without a src attribute.

📝 Syntax

Add defer to an external <script> element:

defer.html
<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

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

</head>

<body>

  <!-- HTML content -->

</body>

</html>

Syntax Rules

  • Boolean attribute: write defer alone or as defer="".
  • Requires a src attribute pointing to an external JavaScript file.
  • Only valid on <script> elements.
  • Do not combine defer and async on the same tag (async wins).

💎 Values

The defer attribute is a boolean attribute. It has no meaningful string values:

  • Attribute present — Script downloads in parallel and runs after HTML parsing, in document order.
  • Attribute absent — Default parser-blocking behavior (unless async is used).
defer-boolean.html
<!-- Deferred external script -->

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



<!-- Equivalent boolean form -->

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

⚡ Quick Reference

ItemDetailsNotes
Element<script src="...">External scripts only
TypeBoolean attributePresence = deferred
DownloadParallel with parsingNon-blocking fetch
ExecutionAfter HTML parsedBefore DOMContentLoaded
OrderDocument order preservedUnlike async
JS propertyscriptElement.defertrue or false

Applicable Elements

ElementSupported?Notes
<script src="...">YesPrimary and standard use
<script> inline (no src)No effectdefer is ignored without src
<link>, <img>NoNot valid on these elements
Module scriptsDeferred by defaulttype="module" behaves like defer

defer vs async

Behaviordeferasync
DownloadParallel with parsingParallel with parsing
When it runsAfter HTML is fully parsedAs soon as download completes
Execution orderPreserved (document order)Not guaranteed
Best forApp scripts that need the DOMIndependent widgets, analytics
Both on same tagAvoid — async takes precedence; defer is ignored
defer-async.html
<!-- Independent analytics: async -->

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



<!-- App logic that needs DOM and order: defer -->

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

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

Examples Gallery

Basic deferred scripts, dynamic JavaScript loading, and preserved execution order.

Example — Deferred External Script

A script in the <head> with defer does not block HTML parsing:

defer-head.html
<head>

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

</head>

<body>

  <h1>Page content</h1>

</body>
Try It Yourself

How It Works

The browser downloads app.js while continuing to parse the body. Once parsing finishes, the script executes and can safely access DOM elements.

Dynamic Values with JavaScript

When creating scripts dynamically, set the defer property before inserting the element:

dynamic-defer.html
<script>

  var scriptElement = document.createElement("script");

  scriptElement.src = "app.js";

  scriptElement.defer = true;

  document.head.appendChild(scriptElement);

</script>
Try It Yourself

How It Works

The dynamically created script inherits deferred behavior when defer is set to true before the element is appended to the document.

Example — Preserved Script Order

Multiple deferred scripts run in the order they appear in the HTML:

defer-order.html
<script defer src="utils.js"></script>

<script defer src="app.js"></script>
Try It Yourself

How It Works

Even if app.js finishes downloading first, the browser waits until parsing completes and runs utils.js before app.js.

♿ Accessibility & UX

  • Faster first paint — Deferring non-critical scripts helps content appear sooner, which benefits all users including those on slow connections.
  • Do not defer critical UI — Scripts that inject essential accessibility features (skip links, focus management) may need to run earlier.
  • Avoid layout shifts — Deferred scripts that modify the DOM after load can cause unexpected jumps; reserve space or use stable markup.
  • Test without JavaScript — Core content should remain usable if scripts fail to load.

🧠 How defer Works

1

Browser finds defer script

Starts downloading the file in parallel.

Fetch
2

HTML parsing continues

Page content renders without waiting for the script.

Parse
3

Document fully parsed

Deferred scripts run in document order.

Execute
=

Fast page, safe DOM access

Scripts run after HTML is ready without blocking rendering.

Browser Support

The defer attribute is supported in all modern browsers for external scripts. It has been widely available since IE 10.

HTML5 · Fully supported

Deferred scripts everywhere

Chrome, Firefox, Safari, and Edge all support defer on external <script> tags.

99% Browser support
Google Chrome Fully supported
Full support
Mozilla Firefox Fully supported
Full support
Apple Safari Fully supported
Full support
Microsoft Edge Fully supported
Full support
Internet Explorer IE 10+ supported
Full support
defer attribute 99% supported

Bottom line: Use defer confidently on external scripts in modern projects.

💡 Best Practices

✅ Do

  • Use defer for app scripts that need the full DOM
  • Keep dependent scripts in document order with defer
  • Place deferred scripts in the head for early download
  • Use async for independent third-party widgets
  • Test script timing with and without defer

❌ Don’t

  • Add defer to inline scripts without src
  • Combine async and defer on the same script tag
  • Defer scripts that must run before HTML renders
  • Assume defer works on dynamically inserted inline code
  • Load interdependent scripts with async

Conclusion

The defer attribute is a valuable tool for optimizing web page loading performance. It lets external scripts download in parallel while HTML parsing continues, then executes them in order after the document is ready.

Use defer for application logic that depends on the DOM. Use async for standalone scripts that do not depend on order or DOM readiness. Never combine both on the same tag.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about defer

Bookmark these before your next script tag.

5
Core concepts
02

Boolean

Presence = defer.

Syntax
⏱️ 03

After Parse

Runs when DOM ready.

Timing
📜 04

Order Kept

Unlike async.

Behavior
05

vs async

Pick the right one.

Compare

❓ Frequently Asked Questions

It defers execution of an external script until after the HTML document is fully parsed, while downloading the file in parallel.
No. defer only applies to <script> elements with a src attribute.
async runs when ready (order not guaranteed). defer waits until HTML is parsed and preserves script order.
Avoid it. If both are present, async takes precedence and defer is ignored.
Yes. Set scriptElement.defer = true on dynamically created script elements before appending them.
Yes in all modern browsers. IE 10 and later also support defer on external scripts.

Load scripts without blocking HTML

Practice the defer attribute with external scripts and preserved execution order in the Try It editor.

Try defer example →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

3 people found this page helpful