Where should <script> tags go, and what do the async and defer attributes do? What does type="module" change?
Show the explanation
Model answer. By default, when the HTML parser meets <script src>, it stops parsing, downloads the script, runs it, then continues. A big script in <head> therefore delays the whole page appearing.
- No attribute: blocks parsing; runs in order. Old advice was to put scripts just before
</body>. - `defer`: downloads in parallel with parsing, and runs after the HTML is fully parsed, in document order, before
DOMContentLoaded. Best for most application scripts that use the DOM. - `async`: downloads in parallel and runs as soon as it arrives, interrupting parsing, in any order. Best for independent scripts such as analytics, which do not depend on the DOM or on each other.
- `type="module"`: loads an ES module. Modules are deferred by default, run in strict mode, and can use
import. Addingasyncmakes them run as soon as they and their imports are ready.
<head>
<script src="/app.js" defer></script>
<script src="https://analytics.example/a.js" async></script>
<script type="module" src="/main.js"></script>
</head>Inline scripts ignore async/defer (except modules). With defer in the head, the browser discovers the file early and still does not block rendering.
Original UniCircle question. Last reviewed 22 Oct 2026.
