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 plus defer / 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>
BehaviorMeaning
DownloadParallel with HTML parsing (non-blocking)
ExecuteAfter document is parsed, in order for multiple deferred scripts
DOMFull 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-patternWhy
Inline onclick="..." everywhereHard to test and maintain; prefer addEventListener in JS
Many blocking scripts in <head>Slows rendering
Loading huge bundles on pages that need almost no JSWasted bytes — ship only what you need

8. Key takeaways

  1. Prefer external scripts with defer or type="module" for maintainability and performance.
  2. async when order and DOM readiness do not matter.
  3. Parser-blocking classic scripts belong at the bottom of <body> if you cannot use defer.

Explain-It Challenge

Explain without notes:

  1. What is the difference between defer and async for <script src="...">?
  2. Why might type="module" be preferable to a classic script for a new project?
  3. 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 →