Suggest an editImprove this articleRefine the answer for “The async attribute in script”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`async` tells the browser to download an external script in parallel with the HTML and to execute it as soon as it has arrived, waiting neither for the DOM nor for other scripts.** Because of that, the execution order of several `async` scripts is arbitrary: whichever file arrives over the network first runs first. The execution itself may briefly interrupt HTML parsing. The attribute suits independent scripts, analytics, widgets, ads, while the main site code uses `defer`. ```html <script src="analytics.js" async></script> <script src="main.js" defer></script> ``` **Key point:** `async` means "run as soon as you are ready and wait for nobody".Shown above the full answer for quick recall.Answer (EN)Image**`async` is a `<script>` attribute that tells the browser to download the script asynchronously, in parallel with the HTML, and to execute it right after it arrives, without waiting for the DOM to be built or for other scripts.** It is the fastest but also the least predictable way to include a script, because the execution order of the files is not guaranteed. ## Theory ### TL;DR - `async` downloads an external script in parallel with HTML parsing, and parsing is not stopped for the download. - As soon as the file has arrived it runs immediately, even if the HTML has not been fully read yet. - That execution can briefly interrupt the parsing of the page. - The order of several `async` scripts is arbitrary and depends on network speed. - `async` and `defer` only apply to external scripts with `src`; inline scripts ignore them. - Use `async` for independent code (analytics, ads, widgets) and `defer` for the main site logic. ### Quick example ```html <head> <!-- independent script: downloads in the background and starts as soon as it is ready --> <script src="analytics.js" async></script> </head> ``` ### How a plain `<script>` works ```html <script src="app.js"></script> ``` What the browser does: 1. Starts reading the HTML. 2. Meets a `<script>`. 3. Stops parsing the HTML. 4. Downloads `app.js`. 5. Executes `app.js`. 6. Continues reading the HTML. So a plain `<script>` **blocks page loading** until it has been executed. ### What `async` does ```html <script src="app.js" async></script> ``` Now: 1. The browser keeps loading the HTML. 2. In parallel it downloads `app.js` in the background. 3. As soon as `app.js` has arrived, it **executes it immediately**, even if the HTML is not finished. That is: - the download is **asynchronous**; - the execution is **immediate**; - the order relative to other scripts is **not guaranteed**. Visually it looks like this: ```text HTML: |-----parsing-----|--------> JS: |---download---|execution| ``` HTML and JS are fetched **in parallel**, but JS execution can interrupt HTML parsing if the script finishes downloading first. ### How it differs from `defer` | Attribute | When the script runs | Order | Blocks HTML | When to use | | --- | --- | --- | --- | --- | | **(no attribute)** | Immediately when met | In order | Yes | Legacy inline code | | `async` | Right after download | Random | May interrupt | Independent scripts (analytics, ads) | | `defer` | After the DOM is built | In order | No | The main site code | The gist: - `async` means "run when you are ready, wait for nobody"; - `defer` means "wait until the DOM is built, then run in order". A combined property table: | Property | `async` | `defer` | | --- | --- | --- | | Downloads in parallel with HTML | Yes | Yes | | Runs as soon as it is downloaded | Yes | No | | Waits for the DOM to be ready | No | Yes | | Preserves script order | No | Yes | | Blocks HTML parsing while executing | Yes, it may interrupt | No | | Ideal for | Independent scripts (analytics, ads, widgets) | The main site logic | ### Several `async` scripts ```html <script src="a.js" async></script> <script src="b.js" async></script> ``` They **may execute in any order**, depending on which file downloads first. So if `b.js` counts on globals defined by `a.js`, that pair will break sooner or later on a slow network. There is another consequence: an `async` script can start before the markup element it needs exists. If the code touches the DOM, either switch to `defer` or wrap the work in a `DOMContentLoaded` handler. ### Correct usage in `<head>` `async` and `defer` work **only for external scripts** (`src="..."`). Inline ones (`<script>...</script>`) ignore these attributes. An example of correct inclusion: ```html <head> <script src="vendor.js" async></script> <script src="main.js" defer></script> </head> ``` Here the analytics-like `vendor.js` is independent and can start at once, while `main.js` depends on the DOM and therefore runs after it has been built. > **An easy way to remember:** > `async` means "download and run as fast as possible", > `defer` means "download early, but wait until the DOM is ready". ### Common mistakes - **Putting `async` on scripts that depend on each other.** The order is random and the dependency will break unexpectedly. - **Touching the DOM from an `async` script.** The element you need may not exist yet; use `defer` or wait for `DOMContentLoaded`. - **Writing `async` on an inline script.** Without `src` the attribute has no effect at all. - **Assuming `async` never blocks the page.** The download does not block, but the execution can interrupt HTML parsing. - **Putting `async` on the main application bundle.** It almost always depends on the DOM and on order, which is a job for `defer`. - **Expecting `DOMContentLoaded` to wait for an `async` script.** The event may fire before such a file has even downloaded.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.