When to Use async vs defer in HTML script Tags – A Complete Guide
This article explains the differences between the default, async, and defer script attributes in HTML, showing how each affects script loading and HTML parsing, with detailed code examples, execution order diagrams, and practical recommendations for choosing the right attribute.
Introduction
During a job interview I was asked to explain the difference between async and defer on a <script> tag. Although the question seemed simple, understanding the three ways to use <script> in HTML is essential for front‑end developers.
Three Ways to Use <script>
Default sequential execution: <script src='https://...'></script> Execute as soon as the script is downloaded: <script src='https://...' async></script> Execute after the HTML document has been parsed:
<script src='https://...' defer></script>Default script (Blocking)
When the browser parses an HTML document and encounters a normal <script> tag, it stops parsing the rest of the HTML, downloads the JavaScript file, executes it immediately, and then resumes parsing. This can cause a white‑screen if a script takes long to load.
Example:
<html lang="zh">
<head>
<script>console.log("Hello log~");</script>
<script src="https://.../Chart.min.js"></script>
<script src="https://.../moment.min.js"></script>
<script src="https://.../vue.min.js"></script>
</head>
<body>您好,我是天天鸭的示例1</body>
</html>Execution order:
Print console.log("Hello log~") Download and execute Chart.min.js Download and execute moment.min.js Download and execute vue.min.js Render body text
async Script (Non‑blocking Download, Blocking Execution)
With the async attribute, the browser continues parsing HTML while downloading the script. Once the download finishes, the script is executed immediately, which temporarily blocks further HTML parsing.
Example:
<html lang="zh">
<head>
<script>console.log("Hello log~");</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>您好,我是天天鸭的示例2</body>
</html>Execution order:
Print console.log("Hello log~") Asynchronously download the three scripts while HTML continues parsing
When a script finishes downloading, it blocks HTML parsing to execute
After execution, HTML parsing resumes
Note: If the HTML structure is simple, the page may display the body text before the scripts run; with complex pages, script execution can interrupt parsing.
defer Script (Non‑blocking Download and Execution)
The defer attribute also allows the browser to continue parsing HTML while downloading the script, but the script is not executed until the entire HTML document has been parsed. Scripts are then executed in the order they appear in the markup.
Example:
<html lang="zh">
<head>
<script>console.log("Hello log~");</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>您好,我是天天鸭的示例3</body>
</html>Execution order:
Print console.log("Hello log~") Asynchronously download the three scripts while HTML parses
After the HTML document is fully parsed, execute the scripts in the order they appear
Note: Multiple defer scripts are downloaded in parallel, but their execution order follows the markup sequence.
Mixed Usage
In real projects you may combine the three methods:
<html lang="zh">
<head>
<script>console.log("Hello log~");</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>您好,我是天天鸭的示例4</body>
</html>Execution order:
Print console.log("Hello log~") Download all scripts in parallel
Because the HTML is simple, the body text appears before script execution moment.min.js finishes first and runs immediately Chart.min.js and vue.min.js wait until HTML parsing completes, then run in markup order
Summary
Default script blocks HTML parsing and runs sequentially. defer does not block parsing; scripts run after the document is fully parsed, preserving markup order. async does not block parsing but executes each script as soon as it finishes downloading, which may block parsing temporarily and leads to unpredictable execution order.
Use async for independent scripts that do not rely on others; use defer when scripts have dependencies or must run after the DOM is ready.
If both async and defer are present, async takes precedence.
Images illustrating the execution flow:
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
