Lesson 3: The <script> Tag, External Scripts & Browser Execution with challenges!

manoj ymkmanoj ymk
6 min read

๐Ÿ”ธ Whatโ€™s the <script> tag?

The <script> tag tells the browser: โžก๏ธ "Hey! Here's some JavaScript. Run it!"

You can put it:

  • Inline, directly inside HTML

  • Externally, loaded from a .js file

  • Modify execution with async or defer


โœ… Example 1: Inline Script

<html>
  <body>
    <p>Before script</p>
    <script>
      alert('Hello, world!');
    </script>
    <p>After script</p>
  </body>
</html>

๐Ÿ•‘ This runs immediately, blocking HTML parsing.


โœ… Example 2: External Script

<script src="script.js"></script>

If script.js contains:

console.log('Running external script');

๐Ÿ”ฅ Itโ€™s cleaner, cacheable, and reusable.


โŒ Invalid: Mixing Inline + src

<script src="script.js">
  console.log('Ignored!');
</script>

Only the external script runs โ€” inline code is ignored.


โœ… Example 3: Multiple External Scripts

<script src="lib.js"></script>
<script src="main.js"></script>

Runs in order, one after another โ€” unless async or defer is used.


โšก Script Loading: async vs defer

AttributeDownload TimingBlocks HTML?Execution TimingOrder Preserved?
(default)Nowโœ… YesImmediately after downloadโœ… Yes
asyncNowโŒ NoImmediately after downloadโŒ No
deferNowโŒ NoAfter HTML parsing completeโœ… Yes

๐Ÿ” Visual Flow

HTML Parsing โ†’
  โ””โ”€โ”€ <script>
        โ””โ”€โ”€ Inline? โ†’ Run now (block)
        โ””โ”€โ”€ External?
            โ”œโ”€โ”€ async โ†’ Download & run ASAP (random order)
            โ”œโ”€โ”€ defer โ†’ Download, wait, then run in order

๐Ÿ”น 2. Fill Any Gaps

๐Ÿ•ณ๏ธ Hidden Quirks

QuirkDetail
type="text/javascript"โœ… Not needed anymore (default is JS)
language="javascript"๐Ÿšซ Obsolete legacy attribute
Inline + src togetherโŒ Only the src runs
Blocking behaviorโณ Scripts pause HTML parsing unless using async or defer
Inline ignores defer/asyncโ— Only external scripts support these attributes
Browser cachingโœ… External scripts are cached and reused

๐Ÿ” Internal Mechanics

HTML is parsed top to bottom.
When a <script> is hit:

  • Parser pauses

  • JavaScript is downloaded (if src)

  • JS is executed

  • Parsing resumes

Unless async or defer are used.


๐Ÿ”น 3. Challenge Me Deeply

โœ… Beginner

  • Add an inline script that logs "Script loaded!"

  • Create log.js and load it via src

  • Prove inline code inside <script src=""> is ignored

๐Ÿงฉ Intermediate

  • Load two scripts (a.js, b.js) with async โ†’ observe unpredictable order

  • Change to defer โ†’ observe guaranteed order

  • Add a script in <head> with defer, log when it runs (after DOM loaded?)

๐Ÿ”ฅ Advanced

  • Dynamically inject a <script src="..."> tag with JS

  • Use script.onload to detect load completion

  • Write a fallback if CDN fails: onerror + local script

  • Measure time difference between blocking vs defer script loading

  • Use document.readyState === 'interactive' check to test defer

๐Ÿง  Brain Twister

Can you write a single HTML file that:

  • Loads external script

  • Logs something before and after it

  • Maintains correct execution order?


๐Ÿ”น 4. Interview-Ready

โœ… Concept-Based Questions

  1. What is the difference between inline and external scripts in HTML?

  2. Why does placing a <script> in the <head> without defer cause page load delays?

  3. Explain the difference between async and defer. When would you use each?

  4. Can a <script> tag have both src and inline code? What happens?

  5. What does defer guarantee in terms of execution timing and order?

  6. Is JavaScript execution synchronous or asynchronous in the browser context?

  7. How does the browser treat inline scripts differently from external ones?


๐Ÿ” Scenario-Based Questions

  1. You have two scripts: vendor.js and app.js. App relies on vendor. How do you ensure correct order without blocking the HTML parse?

    • Expected: Use defer on both; order in HTML determines execution.
  2. Your external script loads too slowly and blocks the rendering. What are your options?

    • Expected: Move script to end of <body>, use defer, or load it async if it's independent.
  3. You're using async, but your dependent scripts break. Why?

    • Expected: async doesn't guarantee execution order โ€” switch to defer.
  4. A script is trying to access a DOM element, but null is returned. What might be the issue?

    • Expected: DOM not yet fully parsed. Either move the script after the element or use defer or DOMContentLoaded.
  5. You use inline JavaScript in <head> that accesses elements in <body>, and it fails. How can you fix this?

    • Expected: Move script to the bottom of <body>, or wrap code in window.onload or DOMContentLoaded.

๐Ÿ›  Debugging Questions

  1. Why would a script that logs to the console not appear in DevTools at all?

    • Expected: Maybe itโ€™s in a <script> tag with both src and inline code โ€” inline is ignored.
  2. Your external script logs โ€œLoadedโ€ but the DOM updates donโ€™t happen. What could go wrong?

    • Expected: Script may run before DOM is ready; need to defer or wait for DOM.
  3. Script works locally but fails on production. What could be causing this?

    • Expected: Caching issues, file not found (check src paths), CSP policies, or missing defer.
  4. You load 3 async scripts and get inconsistent behavior. Why?

    • Expected: Execution order not guaranteed with async.

๐Ÿšฉ Red Flags Interviewers Look For

Red FlagWhy Itโ€™s Bad
Using <script> in <head> without deferBlocks rendering
Mixing src and inline codeOnly src runs, inline ignored
Relying on alert() for debuggingPoor practice
Using async for dependent scriptsRisk of race conditions
Assuming scripts run after DOM automaticallyNot true unless defer, async, or DOMContentLoaded used

โœ… Best Practices to Mention

  • Always use defer for scripts that interact with DOM and donโ€™t need early execution.

  • Use async only for scripts that are truly independent (analytics, ads, etc.).

  • Keep scripts modular and ordered properly.

  • Prefer external scripts for caching and separation of concerns.

  • Use DOMContentLoaded or window.onload for DOM-dependent inline code.


๐Ÿ”น 5. Real-World Usage

AreaUse Case
HTML TemplatesLoad modular scripts per page
SPA FrameworksWebpack/Vite output bundles via <script src="">
AnalyticsLoad Google Analytics / Meta Pixel (often async)
A/B TestingInject scripts based on user groups

๐Ÿ”น 6. Remember Like a Pro

๐Ÿง  Mnemonic

"SRC means Script OR Code โ€“ not both!"

Async = โ€œAs soon as readyโ€
Defer = โ€œDelay until DOM doneโ€

๐Ÿ“Œ Cheatsheet

<!-- โœ… Inline script -->
<script>
  console.log("Hello from inline script");
</script>

<!-- โœ… External script -->
<script src="main.js"></script>

<!-- โœ… External with defer -->
<script src="main.js" defer></script>

<!-- โŒ Don't do this -->
<script src="main.js">
  console.log("This wonโ€™t run");
</script>

๐Ÿ”น 7. Apply It in a Fun Way

๐Ÿ›  Mini Project: Script Execution Tester

Create a simple HTML page that:

  • Loads 3 script tags:

    • One inline

    • One external (log.js)

    • One invalid (src + inline code)

  • Logs order of execution

  • Dynamically creates a <p> tag from each script, color-coded

Bonus Features:

  • Toggle async vs defer

  • Add artificial delay using setTimeout

  • Show timeline bar of which script runs when


๐Ÿง  Extra Value

โœ… Every website uses this โ€” itโ€™s fundamental
โš ๏ธ Common Mistake: Putting scripts too early
๐Ÿš€ Performance Tip: Use defer in <head>
๐Ÿ” Modern Loaders: Use onload / onerror for reliability

0
Subscribe to my newsletter

Read articles from manoj ymk directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

manoj ymk
manoj ymk