How do defer and async attributes for JavaScript improve page performance?
guide // , 6 min read, by Darthwares
The `async` and `defer` attributes for JavaScript improve page performance by allowing the browser to continue parsing HTML while scripts load in the background. This approach prevents script downloads from blocking the construction of the Document Object Model (DOM) or the rendering of the page. As a result, users can see the page content sooner, even before all scripts have finished loading and executing.
On this page // 6 sections
The short version
- JavaScript without `async` or `defer` blocks HTML parsing and page rendering.
- Both `async` and `defer` allow scripts to download in parallel with HTML parsing.
- `async` scripts execute as soon as they download, potentially out of order.
- `defer` scripts execute after HTML parsing is complete and maintain their order.
- Use `async` for independent, non-critical scripts and `defer` for scripts that depend on the DOM or other scripts.
Why does JavaScript block page rendering?
Before a browser can display a web page, it must first build the Document Object Model (DOM) tree by parsing the HTML markup. This process involves reading through the HTML document and constructing a structured representation of the page's content.
During this parsing process, if the browser encounters a JavaScript `<script>` element without specific attributes, it must pause. The parser stops its work to download and execute the script immediately before it can resume parsing the rest of the HTML. This interruption is known as render-blocking JavaScript.
Google for Developers advises minimizing and avoiding the use of blocking JavaScript, especially external scripts that require fetching before they can be executed. Such blocking scripts can significantly delay the initial display of a page to the user.
How do async and defer prevent render blocking?
The `async` and `defer` attributes are instructions to the browser that it can continue parsing the HTML document while simultaneously loading a script in the background. This parallel loading prevents the script download from blocking the construction of the DOM or the rendering of the page.
By allowing HTML parsing and script downloading to occur concurrently, these attributes enable users to see the page content sooner, even before all scripts have fully loaded. This improves the perceived performance and user experience.
Google for Developers states that scripts not critical for the initial page render should be made asynchronous or deferred until after the first render. Deferring the loading and execution of these non-essential scripts until after the initial render or other critical parts of the page have finished loading can reduce resource contention and improve overall performance.
How does the async attribute work?
When the `async` attribute is present on a classic script, the browser fetches the script in parallel with parsing the HTML. MDN Web Docs explains that the script downloads without blocking the page while it is being fetched. Once the download is complete, the script executes at the first available opportunity, before the window's `load` event.
A key characteristic of `async` scripts is that their execution is not guaranteed to follow the order in which they appear in the HTML document. It is possible, and often likely, that `async` scripts will run out of order. MDN Web Docs also notes that while the download is non-blocking, the script's execution itself will block the page from rendering.
Google for Developers recommends using the HTML `async` attribute on external scripts to prevent JavaScript from blocking the parser. However, Google also cautions that asynchronous scripts are not guaranteed to execute in a specified order and should not use `document.write`.
- Downloads in parallel with HTML parsing.
- Executes as soon as it finishes downloading.
- Execution is not guaranteed to be in the order they appear in the HTML.
- Execution can block page rendering once downloaded.
How does the defer attribute work?
The `defer` attribute also tells the browser to fetch the script in parallel with HTML parsing, similar to `async`. However, MDN Web Docs specifies that `defer` indicates the script is meant to be executed after the document has been fully parsed, but before the `DOMContentLoaded` event fires.
Unlike `async` scripts, `defer` ensures that scripts run in the exact order they appear in the HTML document. This attribute is particularly useful for scripts that depend on the Document Object Model (DOM) being fully in place, such as those that modify elements on the page.
MDN Web Docs advises that if your scripts need to wait for parsing and depend on other scripts or the DOM being present, you should load them using `defer`. Additionally, place their corresponding `<script>` elements in the order you want the browser to execute them to ensure proper functionality.
- Downloads in parallel with HTML parsing.
- Executes after HTML parsing is completely finished.
- Executes in the order they appear in the HTML.
- Does not block the parser during download or execution.
When should you use async versus defer?
The choice between `async` and `defer` depends on the script's criticality and its dependencies. Google for Developers suggests that scripts not critical for the initial page render should be made asynchronous or deferred. If it is important for a script to run earlier in the loading process, `async` is the appropriate choice.
For scripts that are less critical or are not needed for the initial view of the page, such as a video player that appears below the fold, `defer` is often more suitable. MDN Web Docs explains that `defer` is useful if your scripts depend on the DOM being in place, for example, if they modify one or more elements on the page.
If your scripts need to wait for the HTML parsing to complete and depend on other scripts or the DOM being fully constructed, you should use `defer`. In such cases, ensure the `<script>` elements are ordered correctly in the HTML to reflect their execution dependencies.
| Characteristic | async | defer |
|---|---|---|
| HTML Parsing | Continues in parallel | Continues in parallel |
| Script Download | In parallel with parsing | In parallel with parsing |
| Script Execution | As soon as downloaded (before window.load) | After HTML parsing (before DOMContentLoaded) |
| Execution Order | Not guaranteed | In HTML order |
| Blocks Rendering | Yes, during execution | No |
Common questions
What is render-blocking JavaScript?
Render-blocking JavaScript refers to scripts that cause the browser to pause its HTML parsing process. When the parser encounters such a script, it must stop, download, and execute the script before it can continue building the Document Object Model (DOM) tree and rendering the page. This delay can prevent users from seeing page content quickly.
What is the main benefit of using async or defer?
The main benefit of using `async` or `defer` is that they prevent JavaScript from blocking the initial rendering of a web page. By allowing scripts to load in the background while the browser continues to parse HTML, these attributes help reduce resource contention and improve overall page performance, letting users see content sooner.
Do async scripts always run in order?
No, `async` scripts are not guaranteed to execute in the order in which they appear in the HTML document. It is possible and often likely that they will run out of order, as they execute at the first opportunity after they finish downloading. For this reason, `async` scripts should not rely on a specific execution order or use `document.write`.
When do defer scripts execute?
Scripts with the `defer` attribute execute after the HTML parsing is completely finished. This execution happens before the `DOMContentLoaded` event fires. `defer` ensures that scripts run in the order they appear in the HTML, making them suitable for scripts that depend on the DOM being fully constructed.
Can async scripts block page rendering?
Yes, while `async` scripts download in parallel without blocking the page, their execution can block page rendering. MDN Web Docs notes that once an `async` script's download is complete, it will execute, and this execution blocks the page from rendering until it is finished.
Primary sources and further reading
This article was researched and written by an AI model and published automatically. It was written from sentences that were checked to appear on the pages below, but a person has not reviewed the text. If something is wrong, tell us at chibivikramathithan@darthwares.com and we will correct it.