Async and Defer attributes in HTML

Async and Defer attributes in HTML

Do you always need to keep your script tag at the bottom of the html page ? Well, when I started programming in HTML I had always known that the script tag has to be placed at the bottom of the HTML file to avoid script errors while accessing the DOM when the document has not rendered completely.

However there are multiple ways in which we can embed the script tag into the HTML and also have a control on the execution of the scripts.

The Problem 🙁

During the HTML parsing when a browser comes across an inline script tag it first executes the script but when the script tag has a reference to an external script file it first downloads and then executes the script. By the time the browser is downloading and executing the scripts the document goes into a blocking state until the referenced scripts are completely downloaded into the browser. This would not be prominent on screen if the size of the script is less. Due to the ever growing popularity of the FrontEnd Frameworks which heavily uses JavaScript the size of the JavaScript file to be downloaded has increased which may lead to the blocking document experience until the script is loaded. Also the script would not be able to attach handlers to the DOM elements that are not yet loaded.

The Solution 👍

One solution to the problem is putting the script tag at the bottom of the page but it would again lead to delays in the script execution if the HTML is long which is a common scenario.

This is where comes the main role of the async and defer attributes of the script tag. Both of these attributes are boolean attributes that could be used with the script tag in the HTML document.
With the help of these attributes we can have a control on the behavior of script load and execution we want while the HTML is rendered in the browser.

Let us go through each on of them -

  1. Defer

The defer attribute is placed in a script tag to defer or postpone the execution of the script until the document is fully loaded and parsed and ready for manipulation by the script. The deferred scripts are run in the order in which they appear in the document when there are multiple script references in the document. The use of defer attribute does not the block the document from rendering.
Modules in JavaScript follows deferred execution by default. It means if the HTML parser encounters a script tag with the type="module" it would not block the document and rather download and execute the module.
Important: The defer attribute can only be used with an external script reference which means that it would only work with the script tag with an src attribute. It would have no effect without an src attribute.

//defer an external script
<script src="example.js" defer></script>
//type=module are deferred by default
<script src="example.js" type="module">
  1. Async

The async attribute is placed in a script tag to execute the script asynchronously while the document is loaded. Just like the defer attribute it does not block the document from rendering rather is executes the script asynchronously. Now there may be multiple script references in the document and those scripts would have different load time based on the size of the script. The presence of async attribute in the script tag ensures that the script is run as soon as it is loaded. This means that the script that gets loaded first would be executed first hence it might be possible a script referenced later in the document which has a small size would get loaded and executed first as compared to a heavy script present at the start of the document.
As mentioned in the section above that the script of type="module" follows deferred execution by default. This behavior can be overwritten by using the async attribute which would execute the script once the module and all of its dependencies are loaded.

//asynchronously loading and executing script
<script src="example.js" async></script>


In this post we learned how are the scripts loaded and executed by default and what is the problem of loading and executing the script in the traditional way.
We also learned that with the help of the defer and async attribute of the script tag we can have a control over the way in which the scripts could be loaded and executed.
I hope you enjoyed this article and found it to be useful. I am trying to share my knowledge with the help of these simple but useful topics to help you with your task. You can subscribe to my newsletter to receive the latest post directly in your mailbox. Thanks for reading and see you in the next post 👋 Happy Coding 🙂

Book Recommendation

I would recommend you to refer to the book JavaScript - The Definitive Guide by David Flanagan for an in-depth understanding of the JavaScript Language.