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 and defer.
  • 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

  1. When should you prefer defer over async?
  2. What does type="module" change about script loading and scope?
Show answers
  1. Use defer for app scripts that depend on DOM order; async is for independent scripts where order doesn’t matter.
  2. Modules are deferred by default, run in strict mode, and have their own scope with import/export.

Exercises

  1. Convert an inline script to an external app.js, include it with defer, and verify execution order.
  2. Create a small module pair (main.js, lib.js) using export/import and include via type="module".