What does defer do in <script>?
Definition
deferis a<script>tag attribute that tells the browser:"Load this script in parallel with the HTML, but run it only after the entire HTML document has been loaded and parsed (DOMContentLoaded)."
1. Normal behavior without defer
<script src="app.js"></script>What happens:
- The browser starts loading the HTML.
- It encounters
<script>. - It stops parsing the HTML to:
- download
app.js, - run it.
- Only then does it continue loading the page.
As a result, the page loads more slowly, because the JS blocks the HTML.
2. What defer does
<script src="app.js" defer></script>Now the browser:
- Starts loading HTML and JS in parallel.
- Does not block HTML parsing.
- Runs
app.jsonly after the DOM is fully built, but before theDOMContentLoadedevent.
In other words:
- the HTML is parsed ->
- the script loads in the background ->
- the DOM is ready ->
- the script runs ->
- ->
DOMContentLoadedfires.
3. Example of the difference
<!-- Without defer -->
<script src="slow.js"></script>
<p>Hello!</p>
<!-- With defer -->
<script src="slow.js" defer></script>
<p>Hello!</p>With defer, the text "Hello!" appears immediately,
while the script is still loading.
Without defer, the page hangs until slow.js finishes loading.
4. When there are several scripts
<script src="a.js" defer></script>
<script src="b.js" defer></script>Scripts with defer:
- load in parallel,
- but run in the order they appear in the HTML.
This is the main difference from async, where the order is not guaranteed (see below).
5. The difference between defer and async
| Attribute | When it loads | When it runs | Guaranteed order | Typical scenario |
|---|---|---|---|---|
| (no attribute) | Immediately, on encounter | Immediately (blocks HTML) | Yes | Legacy JS in <head> |
| async | In parallel with HTML | Right after loading (does not wait for DOM) | No | Analytics, ads, widgets |
| defer | In parallel with HTML | After the DOM is built | Yes | Main application scripts |
6. Compatibility
Works in all modern browsers.
When used in <head>, it is the most correct way to include JS:
<head>
<script src="main.js" defer></script>
</head>The browser does not block page loading and guarantees your code runs once the DOM is already ready.
7. Effect on DOMContentLoaded
DOMContentLoaded fires after all defer scripts have run.
So you can be certain that by the time this event fires, your scripts have already executed.
Summary
| Property | No attribute | async | defer |
|---|---|---|---|
| Loads the script | Immediately (blocks HTML) | In parallel | In parallel |
| Runs the script | Right after loading | Right after loading | After the HTML is parsed |
| Execution order | In order | Arbitrary | In order |
| Blocks HTML | Yes | No | No |
| Waits for the DOM | No | No | Yes |
Simple rule of thumb:
defermeans "load right away, run later".- Use it for main JS files, so the page loads fast without "white screens".
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.