Where to Place JavaScript in HTML: Beginner Guide to Script Loading & Performance

Where to Place JavaScript in HTML: Beginner Guide to Script Loading & Performance

Head vs. Body Placement, External Scripts, and How to Prevent Slow Page Loads

Author
Nguyen Bao Huy
13:31:00 30/01/2026
2 min read
0 comments
Quick Answer (TL;DR):
You can place JavaScript in three locations: inside the <head>, at the bottom of the <body>, or in an external .js file linked via <script src="...">.
For modern web development, the recommended approach is linking an external .js file inside the <head> using the defer attribute. This allows HTML parsing to continue without interruption while your script downloads in parallel.

The Common Beginner Bug: "Cannot read properties of null"

When you start learning JavaScript, you might write code to update an element on the screen, only to see an error in the browser console:

bash
Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')

This error happens because browsers read HTML files sequentially from top to bottom. If a script executes before the browser reaches the targeted HTML element, the script searches for an element that does not yet exist in memory.

Understanding how script placement controls execution timing prevents this issue entirely.

1. Internal JavaScript: The <script> Tag

You can embed JavaScript directly into an HTML file by wrapping the code between <script> and </script> tags.

Option A: Inside the <head> Section

Placing scripts inside <head> groups configuration and metadata at the top of your document.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Script in Head</title>
  <script>
    // Functions can safely live here if called later by events
    function updateGreeting() {
      document.getElementById("status").innerHTML = "Welcome back!";
    }
  </script>
</head>
<body>
  <p id="status">Hello, guest.</p>
  <button type="button" onclick="updateGreeting()">Sign In</button>
</body>
</html>

When to use: Storing standalone functions or analytics tracking snippets that must register before visual elements render.

Caution: Avoid running immediate DOM manipulation commands directly in <head> without wrapping them in an event listener.

Option B: At the Bottom of the <body> Section

A traditional beginner pattern places <script> tags right before the closing </body> tag.

index.html
<!DOCTYPE html>
<html lang="en">
<body>
  <h2>Interactive Header</h2>
  <p id="welcome-message">Loading...</p>

  <!-- Place your script directly before the closing body tag -->
  <script>
    // Safe: the browser has already parsed #welcome-message above
    document.getElementById("welcome-message").innerHTML = "Page content loaded successfully!";
  </script>
</body>
</html>

Why this works: By the time the browser reaches the script, all HTML elements above it are fully parsed and ready for interaction.

2. External JavaScript: The Production Standard

Instead of mixing JavaScript into HTML documents, save your code in a dedicated file with a .js extension (e.g., app.js).

main.js
// file: main.js
function showNotification() {
  document.getElementById("alert-box").innerHTML = "Profile updated!";
}

Link the script using the src (source) attribute inside an HTML <script> tag:

html
<script src="main.js"></script>
Important: External script tags must remain empty. Do not place code inside <script src="...">Your code here</script>.

3 Key Advantages of External Files:

  • Separation of Concerns: Keeps design markup (HTML) separate from business logic (JavaScript).
  • Browser Caching: Browsers download external .js files once and store them in local cache, accelerating future page loads.
  • Maintainability: Updating a shared navigation bar or authentication script in one file applies the change across your entire site.

3. How to Reference External Scripts

Depending on where your JavaScript files live, you can reference them using three URL formats:

A. Relative Path (Same folder or subfolder)

Best for standard multi-page sites:

html
<!-- Script is in the exact same folder as the HTML file -->
<script src="main.js"></script>

<!-- Script is in a dedicated /scripts subfolder -->
<script src="scripts/main.js"></script>

B. Absolute Root-Relative Path

Best when serving files through local dev servers (such as Next.js or Vite):

HTML

html
<!-- Always resolves from your domain root: yourdomain.com/js/main.js -->
<script src="/js/main.js"></script>

C. Full External URL (CDN)

Best for including third-party libraries, utility tools, or fonts:

HTML

html
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script>

4. Modern Best Practice: The defer Attribute

Modern web standards favor placing external script tags in the <head> along with the defer attribute:

HTML

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Modern Script Placement</title>
  
  <!-- Non-blocking: downloads in background, executes after HTML parses -->
  <script src="app.js" defer></script>
</head>
<body>
  <h1 id="headline">Content</h1>
</body>
</html>

How defer Works Under the Hood:

  1. The browser spots <script src="app.js" defer>.
  2. It downloads the file in the background without pausing HTML parsing.
  3. It guarantees execution only after the full HTML tree is ready, maintaining clean load performance.

Quick Comparison: Script Placement Strategies

TechniqueWhere It LivesPage Load ImpactSafe for Immediate DOM Access?
Direct <head><head>Blocks HTML rendering until parsedNo (Throws null reference error)
Bottom of <body>Before </body>Renders HTML first, then runs JSYes (Elements exist in DOM)
External defer<head> with deferOptimal (Parallel background downloadYes (Executes right after DOM builds)
External async<head> with asyncRuns immediately after download finishesRisky (Order not guaranteed)

Summary Checklist for Beginners

  • Use external .js files whenever code spans more than a few lines.
  • If writing a quick demo or prototype, placing the <script> before </body> prevents missing element errors.
  • For real-world web projects, place external scripts inside the <head> using <script src="..." defer></script> for the cleanest balance of organization and loading speed.

First Lesson

You are at the beginning of this curriculum.

Latest Tutorial

More chapters coming soon to this topic.

Author avatar

Nguyen Bao Huy

Lead Fullstack & AI Solutions Engineer

Specializing in Next.js App Router, React 19, TypeScript, and modern design systems. Passionate about creating seamless user experiences.

Discussion

0

No comments yet

Be the first to share your thoughts, question a concept, or provide additional tips!

Leave a Reply

Share your insights, questions, or solutions with the developer community.

Your avatar
0 / 500 characters