defer, and asyncYou can place JavaScript inside HTML using external .js files, internal <script> blocks, or inline event attributes. External files with the defer attribute give the best balance of page speed and clean code.
script, async, and defer Load ScriptsBy default, a <script> tag pauses HTML parsing while the browser downloads and runs the file. Adding defer downloads the script in parallel and waits until HTML parsing finishes.
flowchart TD
subgraph Default ["Default script tag"]
H1["Parse HTML"] --> P1["Pause HTML"] --> F1["Download & Run JS"] --> R1["Resume HTML"]
end
subgraph Async ["script async"]
H2["Parse HTML + Download JS"] --> P2["Pause HTML & Run JS"] --> R2["Resume HTML"]
end
subgraph Defer ["script defer"]
H3["Parse HTML + Download JS"] --> D3["Finish HTML"] --> E3["Run JS in Order"]
end
Use this guide to pick the right loading strategy for each script on your page:
defer: Best for app code that reads or updates DOM elements and needs predictable order.async: Best for independent scripts like analytics that do not touch the DOM or depend on other scripts.<script> before </body>: Useful for small page-specific snippets after the main HTML markup finishes loading.Put your deferred external script inside <head> so the browser starts downloading it early while parsing HTML.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Script Placement Demo</title>
<script src="app.js" defer></script>
<script src="analytics.js" async></script>
</head>
<body>
<h2>Order Summary</h2>
<p id="status">Loading order details...</p>
<script>
document.addEventListener("DOMContentLoaded", () => {
const statusEl = document.getElementById("status");
if (statusEl) {
statusEl.textContent = "Page ready for interaction.";
}
});
</script>
</body>
</html>
<head>: A <script src="bundle.js"></script> without defer freezes rendering on slow mobile networks.defer to inline scripts: Browsers ignore defer and async on <script> blocks that have no src attribute.async for dependent files: Scripts marked async execute as soon as they finish downloading, so order is never guaranteed.<head> or before </body>?Putting <script src="app.js" defer></script> inside <head> is better than placing a blocking script before </body>. The browser starts fetching the file sooner while still waiting for the DOM.
Yes, you can link as many <script> files as needed, or bundle modules with ES import. When multiple scripts use defer, they run in exact document order.
onclick attributes in HTML?Inline handlers mix logic with markup and fail strict Content Security Policy rules. Use addEventListener() in an external .js file instead.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.