Suggest an editImprove this articleRefine the answer for “How does "defer" differ from "async" in <script>?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)Both **`defer`** and **`async`** load a script asynchronously without blocking HTML parsing, but they differ in when the script runs: `defer` runs the script only after HTML parsing finishes and preserves script order, while `async` runs it as soon as it loads, in unpredictable order. **Key point:** `defer` suits the site's main logic that depends on the DOM, while `async` suits independent scripts such as analytics or ads.Shown above the full answer for quick recall.Answer (EN)Image## The problem that `defer` and `async` solve When the browser encounters the tag: ```javascript <script src="script.js"></script> ``` by default it: 1. **Stops parsing the HTML**, 2. Loads `script.js`, 3. Executes it, 4. Only then **continues building the DOM**. This blocks the page's render, so the user sees a "blank screen" until the JS loads. That's why the `defer` and `async` attributes appeared, to **avoid blocking HTML parsing**. --- ## `defer` ```javascript <script src="script.js" defer></script> ``` **How it works:** 1. The script **loads in parallel** with the HTML (asynchronously). 2. But it **executes only after the HTML has fully finished parsing**, that is, **once the DOM is ready**, but **before the** `DOMContentLoaded` **event**. 3. Scripts with `defer` execute **in the order they're listed in the HTML**. It's great for an application's "main" scripts (for example, `main.js`, `vendor.js`). Example: ```javascript <script src="a.js" defer></script> <script src="b.js" defer></script> ``` Both load **in parallel first**, but they execute **strictly in order:** `a.js` **then** `b.js`, after the DOM is built. --- ## `async` ```javascript <script src="script.js" async></script> ``` **How it works:** 1. The script **loads in parallel** with the HTML (like `defer`), 2. But it **executes immediately after it loads**, even if the HTML hasn't finished parsing yet. 3. Scripts with `async` execute **in an unpredictable order**, depending on which one finishes loading first. It's suited for **independent** scripts (for example, analytics, ads, metrics). Example: ```javascript <script src="a.js" async></script> <script src="b.js" async></script> ``` `b.js` can execute **before** `a.js` if it loads faster, even if it appears lower in the HTML. --- ## Comparing `defer` and `async` | Property | `defer` | `async` | |---|---|---| | Script loading | Asynchronous (in parallel with HTML) | Asynchronous | | Execution | After HTML fully finishes parsing | Right after loading | | Execution order | Preserved | Not guaranteed | | Blocks HTML parsing | No | No | | `DOMContentLoaded` event | Waits for all `defer` scripts to run | Doesn't wait | | Typical scenarios | The site's main logic | External trackers, ads | --- ## A visual example ```javascript <!-- HTML is being parsed... --> <script src="main.js" defer></script> <script src="analytics.js" async></script> ``` The process: | Stage | What happens | |---|---| | 1 | The browser starts parsing the HTML | | 2 | Both scripts load simultaneously | | 3 | `analytics.js` (async) loads faster, so it executes **right away** | | 4 | The HTML finishes parsing | | 5 | Then `main.js` (defer) executes | | 6 | Then `DOMContentLoaded` fires | --- ## Conclusions | Attribute | When to use it | |---|---| | `defer` | For the site's main JS code that depends on the DOM (for example, initializing the interface) | | `async` | For independent scripts (analytics, metrics, ads) | | **No attributes** | Only when you need to block HTML parsing (rarely needed) | --- ## A tip If you use a **modern bundler** (Next.js, Vite, Webpack), it already adds `defer` to `<script>` tags in `head` for you, so in modern applications **this is already the default best practice**.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.