Understanding async and defer in HTML <script> Tags
Daniel Hayes
Full-Stack Engineer · Leapcell
Every web developer proudly claims to be proficient in HTML. But… do you really know the difference between async
and defer
in <script>
?
These attributes are common in modern frontend web applications but are often overlooked.
Let's summarize first. In HTML, a <script>
tag can be used in three ways, which will be explained one by one below:
- Default sequential execution:
<script src='https://...'></script>
- Execute immediately after download:
<script src='https://...' async></script>
- Execute after the document is fully parsed:
<script src='https://...' defer></script>
<script>
Explanation
When a browser encounters a default <script>
tag while parsing an HTML document:
- It blocks parsing of the remaining HTML.
- It loads the JavaScript script, and once the script is fully loaded, it executes immediately.
- After execution, HTML parsing resumes.
Consider the following example:
<html lang="zh"> <head> <script> console.log('First script'); </script> <script src="https://.../Chart.min.js"></script> <script src="https://.../moment.min.js"></script> <script src="https://.../vue.min.js"></script> </head> <body> Page content 1 </body> </html>
Execution order:
- Logs
console.log("First script");
- Downloads and executes the external script
Chart.min.js
- Downloads and executes
moment.min.js
- Downloads and executes
vue.min.js
- Displays text content: Page content 1
Note
A default <script>
executes scripts in order. If one script takes too long to execute, the subsequent scripts will be queued, and HTML parsing will be paused. This can result in a white screen until execution completes.
<script async>
Explanation
When the browser encounters a <script>
tag with the async
attribute:
- It does not block HTML parsing but asynchronously fetches the JavaScript script.
- Once the script finishes downloading, it immediately executes, pausing HTML parsing at that moment.
- After execution, HTML parsing resumes.
Consider the following example:
<html lang="zh"> <head> <script> console.log('First script'); </script> <script async src="https://.../Chart.min.js"></script> <script async src="https://.../moment.min.js"></script> <script async src="https://.../vue.min.js"></script> </head> <body> Page content 2 </body> </html>
Execution order:
- Logs
console.log("First script");
- Asynchronously downloads
Chart.min.js
,moment.min.js
, andvue.min.js
while HTML parsing continues. - Once a script is downloaded, it immediately executes, pausing HTML parsing.
- HTML parsing resumes after script execution.
Note
Scripts with async
pause HTML parsing during execution but not during download. If the HTML structure is simple, it may fully load before scripts execute, meaning "Page content 2" appears first, then scripts run.
If the HTML structure is complex and takes longer to parse, parsing may be interrupted when scripts execute.
<script defer>
Explanation
When the browser encounters a <script>
tag with the defer
attribute:
- It does not block HTML parsing but asynchronously fetches the JavaScript script.
- Once the script finishes downloading, it does not execute immediately.
- The script executes only after the entire HTML document has been fully parsed.
Consider the following example:
<html lang="zh"> <head> <script> console.log('First script'); </script> <script defer src="https://.../Chart.min.js"></script> <script defer src="https://.../moment.min.js"></script> <script defer src="https://.../vue.min.js"></script> </head> <body> Page content 3 </body> </html>
Execution order:
- Logs
console.log("First script");
- Asynchronously downloads
Chart.min.js
,moment.min.js
, andvue.min.js
while HTML parsing continues. - Scripts do not execute immediately; they wait until HTML parsing completes and "Page content 3" is displayed.
- Executes the downloaded scripts in order.
Note
If multiple defer
scripts are present, the browser downloads them in parallel. Regardless of download speed, execution order follows the sequence in the HTML document.
Mixed Usage
In real-world scenarios, different methods can be combined. Consider the following example:
<html lang="zh"> <head> <script> console.log('First script'); </script> <script defer src="https://.../Chart.min.js"></script> <script async src="https://.../moment.min.js"></script> <script defer src="https://.../vue.min.js"></script> </head> <body> Page content 4 </body> </html>
Execution order:
- Logs
console.log("First script");
- Asynchronously downloads
Chart.min.js
,moment.min.js
, andvue.min.js
. - Because the HTML is simple, it fully loads before script execution, displaying "Page content 4" first.
moment.min.js
executes immediately after downloading.Chart.min.js
andvue.min.js
execute after HTML parsing completes.
Summary
- Default
<script>
blocks HTML parsing and executes scripts in sequence. defer
does not block HTML parsing, ensures scripts execute in document order, and runs scripts after HTML parsing completes.async
may block HTML parsing but executes scripts in download order, which is unpredictable.
Best Practices
- If a script is independent and does not rely on other scripts or resources,
async
is a good choice (though it may block parsing temporarily). - If scripts depend on each other, use
defer
to ensure order. - If both
async
anddefer
are present,async
takes priority.
We are Leapcell, your top choice for hosting Node.js projects.
Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:
Multi-Language Support
- Develop with Node.js, Python, Go, or Rust.
Deploy unlimited projects for free
- pay only for usage — no requests, no charges.
Unbeatable Cost Efficiency
- Pay-as-you-go with no idle charges.
- Example: $25 supports 6.94M requests at a 60ms average response time.
Streamlined Developer Experience
- Intuitive UI for effortless setup.
- Fully automated CI/CD pipelines and GitOps integration.
- Real-time metrics and logging for actionable insights.
Effortless Scalability and High Performance
- Auto-scaling to handle high concurrency with ease.
- Zero operational overhead — just focus on building.
Explore more in the Documentation!
Follow us on X: @LeapcellHQ