JavaScript - Script Placement
Overview
Estimated time: 15–25 minutes
Where and how you include scripts affects when they execute and page responsiveness.
Learning Objectives
- Use external scripts for caching and cleanliness.
- Choose between
async
anddefer
. - Load ES modules with
type="module"
.
Prerequisites
Inline vs External
<!-- Inline -->
<button id="b">Click</button>
<script>
document.getElementById('b').addEventListener('click', () => alert('Hi'));
</script>
<!-- External -->
<script src="app.js"></script>
Defer vs Async
- defer: downloads in parallel, executes after parsing, preserves order. Good default for app scripts.
- async: downloads in parallel, executes when ready (order not guaranteed). Good for independent scripts.
<script defer src="app.js"></script>
<script async src="analytics.js"></script>
Modules
<script type="module" src="main.js"></script>
// main.js
import { greet } from './lib.js';
console.log(greet('World'));
DOMContentLoaded
document.addEventListener('DOMContentLoaded', () => {
// safe to query and bind handlers
});
Best Practices
- Prefer external files and
defer
. - Avoid large inline scripts in HTML.
- Use
type="module"
for modular codebases.
Checks for Understanding
- When should you prefer
defer
overasync
? - What does
type="module"
change about script loading and scope?
Show answers
- Use
defer
for app scripts that depend on DOM order;async
is for independent scripts where order doesn’t matter. - Modules are deferred by default, run in strict mode, and have their own scope with
import
/export
.
Exercises
- Convert an inline script to an external
app.js
, include it withdefer
, and verify execution order. - Create a small module pair (
main.js
,lib.js
) usingexport
/import
and include viatype="module"
.