Defer vs async script JavaScript

You can load JavaScript files asynchronously to reduce render-blocking with the defer and async attributes on the script tag, but what's the difference between them? Here are the differences between defer and async for loading script files.

First, here is why they are useful.

What is render-blocking JavaScript?

Render-blocking JavaScript (more specifically parser-blocking) is when a script pauses the parsing of an HTML document and DOM tree construction while the script is loading or executing. This slows down your page speed because your page can only be seen once the HTML is parsed and rendered.

An HTML script tag without the defer or async attributes will load and run the script as soon as it is reached, which will block the parsing and rendering of the HTML content of the page until the script has been downloaded and executed.

<script type="text/javascript" src="script.js"></script>

To avoid render-blocking JavaScript, it became good practice to place the script tags near the end of your HTML just before the closing </body> tag to make sure the HTML was loaded first. But now that we have defer and async we no longer need to do that. A script placed in the <head> of your page with either the defer or async attribute will load in parallel at the same time as the HTML is parsed instead of afterwards.

Defer vs async

The defer attribute and async attribute both download the script asynchronously at the same time as the HTML is parsed, but defer waits until the HTML is fully parsed before executing the script just before the DOMContentLoaded event whereas async pauses the parsing of the HTML to execute the script as soon as it is downloaded.

/* defer script tag */
<script defer type="text/javascript" src="script.js"></script>

/* async script tag */
<script async type="text/javascript" src="script.js"></script>

The defer attribute guarantees that your scripts will execute in source order, the order they are written in the page, whereas async does not guarantee source order and executes scripts in whatever order they are finished downloading first.

This means that defer is best for scripts that are dependent on other scripts because async may execute smaller scripts first.

Both defer and async can only be used on external script tags that have a src attribute, not inline scripts where the JavaScript is written inside the script tags.

When using defer or async, place the script in the <head> of the page so it can start downloading the JavaScript in parallel as soon as possible, otherwise it will only find and load the scripts after the HTML is parsed instead of at the same time.

defer is best for most cases and allows fastest HTML parsing. Since defer waits until the HTML is parsed before executing the script, it is also best for scripts that rely on the DOM being available before script execution. Since defer also respects source order, it is also best for scripts that rely on other scripts.

async is used for completely independed JavaScript like ads or analytics which don't rely on other scripts and don't need the DOM to be available before script execution and where execution order doesn't matter.

With defer you don't have to check for the load event or DOMContentLoaded event in your JavaScript to access the DOM because deferred scripts are only executed once the HTML is already parsed and the DOM is constructed, just before DOMContentLoaded.

If you use async but only want the script or certain parts of your script to run after the load event or DOMContentLoaded event, you can write your JavaScript inside an event listener for on load in vanilla JavaScript.

Thanks for reading.
Ryan

Published on 30 Jul 2022
Last modified on 31 Jul 2022