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.
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>
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.js
to 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.
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>
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.