All You Need to Know About Async & Defer

Async and Defer are attributes that are commonly used within HTML tags, especially the script tag. We typically use the script tag at the beginning of an HTML document when we need to load executable code, usually JavaScript, from an external source.

However, the script tag is blocking in nature, which means that when a browser encounters it, it automatically delays rendering DOM elements until the script finishes loading.

Therefore, if a script is heavy, the entire page will remain blank until the script has loaded, which can result in a poor user experience. Thanks to Async and Defer, we have a way to get out of this situation.

In this article, we will elaborate, why and when to use Async & Defer to get the best results out of it.

<div>Before Script Tag </div>
<script defer src="app.js" ></script>


<!-- this div will be visible after app.js execution-->
<div>After Script Tag</div>

Before moving into the Async and Defer, hold a for a sec, please. Because some of might wonder what about using a script at the end of the HTML document? Well, my friend, this might a solution but not a sustainable solution.

When an HTML page is rendering slowly at that moment some functionality or code may break because the script isn't immediately available yet. So we need to load script parallely when dom content is also rendering. 

Table of Contents

  1. What is Defer ? 
  2. When to use Defer?
  3. What is Async ? 
  4. When to use Async ?

What is Defer ?

To simplify things, we previously explained that the script tag blocks the rest of the DOM until it finishes executing. However, there's a catch: while scripts can be loaded or retrieved without blocking the rest of the HTML, their execution still blocks it.

To get around this, we can use the Defer attribute. By using Defer, our script will load asynchronously alongside DOM parsing, and then execute before the DomContentLoaded event.

<div>Before Script Tag </div>
<script defer src="app.min.js" ></script>


<!-- this div will be visible immediately  -->
<div>After Script Tag</div>

When to use Defer?

Suppose, you have multiple scripts in your HTML document. Out of them, one script may be crucial for the functionality of the webpage, so it needs to be executed first before any other script. In this case, we must use Defer as it maintains the relative order of the scripts, even if one script requires more time than the others.

For example:

<div>Before Script Tag </div>
<script defer src="app.max.js" ></script>
<script defer src="app.min.js" ></script>


<!-- this div will be visible immediately  -->
<div>After Script Tag</div>

Here, if Script app.min.js finishes its loading before app.max.js, it will still have to wait forapp.min.jsto be loaded and finished before executing.

Another important fact is that the Defer attribute only applies to external scripts with a src attribute, indicating that it is not applicable to inline scripts.

What is Async ?

Async Scripts are completely different from Defer. Async Scripts are fully independent, meaning they don't wait for the DomContentLoaded event and the DomContentLoaded event doesn't wait for Async Scripts.

Additionally, Async Scripts don't maintain the relative order of scripts. They work on a first-come, first-served basis, meaning that scripts with the shortest loading/execution time will get priority, regardless of their position.

<div>Before Script Tag </div>
<script async src="app.max.js" ></script>
<script async src="app.min.js" ></script>


<!-- this div will be visible immediately  -->
<div>After Script Tag</div>

When to use Async ?

Using Async can be tricky, and it requires careful consideration. Since Async Scripts don't wait for the DOMContentLoaded event, there is a possibility that the HTML DOM may be loaded faster than Async Scripts execution, potentially causing functionality issues.

Additionally, since Async doesn't maintain the relative order of scripts, less important scripts may be loaded before critical ones. Therefore, it is recommended to use Async Scripts for independent features like chat or comment sections, counters, ads and so on, as they don’t depend on our scripts, and our scripts shouldn’t wait for them, rather than critical scripts.