Episode 1 — Fundamentals / 1.13 — Introduction to JavaScript
1.13.c — Linking JS with HTML (<script>)
In one sentence: You connect JavaScript to a page with the
<script>element — either inline code or an external file — and you control when it runs using placement plusdefer/async/type="module".
Navigation: ← 1.13.b — Where JavaScript Runs · 1.13.d — Console Debugging →
1. Inline script
<script>
console.log("Runs immediately when the parser reaches this tag.");
</script>
Pros: Quick experiments. Cons: No caching, mixes logic into HTML, blocks HTML parsing unless deferred (see below).
2. External script (preferred)
<script src="./app.js"></script>
The browser fetches app.js and executes it. Use a relative or absolute URL. External files are cacheable by the browser and easier to maintain.
3. Classic scripts and parser blocking
A classic <script src="..."> without defer or async blocks HTML parsing while the file is downloaded and executed. That can delay first paint — bad for performance.
Traditional fix: Put scripts at the end of <body> so the DOM exists before your code runs.
4. defer — download early, run after HTML is parsed
<script src="./app.js" defer></script>
| Behavior | Meaning |
|---|---|
| Download | Parallel with HTML parsing (non-blocking) |
| Execute | After document is parsed, in order for multiple deferred scripts |
| DOM | Full DOM available before your script runs |
Best default for most bundled apps: put one deferred script in <head> or before </body>.
5. async — run as soon as downloaded
<script src="./analytics.js" async></script>
Scripts run as soon as they arrive; order between async scripts is not guaranteed. Good for independent snippets (analytics), bad if one file depends on another.
6. ES modules
<script type="module" src="./app.js"></script>
Modules are deferred by default, use strict mode implicitly, and support import / export. Each module is evaluated once. Use for modern applications.
7. What to avoid
| Anti-pattern | Why |
|---|---|
Inline onclick="..." everywhere | Hard to test and maintain; prefer addEventListener in JS |
Many blocking scripts in <head> | Slows rendering |
| Loading huge bundles on pages that need almost no JS | Wasted bytes — ship only what you need |
8. Key takeaways
- Prefer external scripts with
deferortype="module"for maintainability and performance. asyncwhen order and DOM readiness do not matter.- Parser-blocking classic scripts belong at the bottom of
<body>if you cannot usedefer.
Explain-It Challenge
Explain without notes:
- What is the difference between
deferandasyncfor<script src="...">? - Why might
type="module"be preferable to a classic script for a new project? - Where should a blocking classic script go if you cannot use
defer, and why?
Navigation: ← 1.13.b — Where JavaScript Runs · 1.13.d — Console Debugging →