Async VS Defer Script Tags

Async VS Defer Script Tags

Loading external scripts into HTML using the script tag is probably essential. Although it is actually so essential, problems can occur.

With HTML5 , we got two new boolean attributes for the <script> tag: async and defer. Which allows us to specify how our external JavaScript should be Loaded

So in this article we will talk about the difference between these tags and how to use them.

Why should you use async and defer at all?

In HTML, loading and execution of external scripts can lead to errors , probably every developer has experienced it. The error occurs usually because the<script> is placed in wrong order, as HTML document is read and executed by the browser from top to bottom - at least that's the standard for our script-tags, which can contain JavaScript code themselves, or refer to an external file.

Let's have a look at an example for a problem that occurs frequently.

carbon(15).png

Our console.log will output "null" because we are executing the JavaScript before the h1 is available in the DOM. So the querySelector cannot access the element, because it does not exist yet in DOM.

It is important to understand that the whole thing comes about because JavaScript also blocks our DOM construction as soon as browser encounters the script it is loaded and executed immediately even though it should actually access the DOM, which doesn't exist yet at that time. This happens because browser prioritizes the script for that moment.

That's not the only problem

We know that we can avoid the error occurring in the above code can be resolved by placing the <script> at the end of <body> tag as shown in the below code

carbon(16).png

When we place the <script> tags at the end, they are only loaded and executed when the DOM is ready, i.e the page is already visible to the user.

But now if the browser encounters the script, even it is at the end of the page, it must first be completely loaded and executed when the DOM is ready, i.e the page is visible to user but the user cannot interact with it till the scripts are loaded and executed.

In today's world no one fancies slow websites, Hence the above approach is not optimal I would say especially on slow mobile devices with a bad internet connection. In order to overcome this async and defer are used

Async

Async is an attribute for the classic script tag when we use it to include external script. Using it correctly is easy and looks like this.

<script src = "jquery.js" async></script>

So we just have to include the async as attribute as shown in the above code.

async means that our script is loaded parallel to all other resources and the browser can build the DOM and load the script simultaneously. Async guarantees that loading the script no longer blocks the DOM.

Here's how the page loads a script with async, put in head tag.

with-async.png

You can see in the above figure that the browser starts parsing the HTML doc from top to bottom when it reaches to script tag with async the script is fetched asynchronously and when it's ready HTML parsing is paused to execute script, then the HTML parsing is resumed.

Important thing to notice here is that only loading the script will not block the parsing of HTML doc, but execution does, so we have to wait till the script gets executed. So the problem that our script wants to access something in the DOM, but at the moment it doesn't even exist, can also occur here.

Defer

Beside aync there is also defer, with which we can influence the loading behaviour of our scripts.

Just like async, defer does not block the browser when loading the script.

With async, the decisive point was that async might block the browser during execution this is not the case with defer.

The use of defer is as easy as async as shown below

<script src = "jquery.js" defer ></script>

The script included with defer, is only executed when the DOM is ready therefore defer is ideal for scripts that are guaranteed to access the DOM.

Common to both async and defer is that the scripts are loaded in parallel to the construction of the DOM — only when the scripts are executed is different for both. With defer they are guaranteed to be executed only when the DOM is ready.

with-defer.png

You can see in the above figure that the script with defer are fetched without pausing the parsing of HTML. Once the HTML parsing is finished, the scripts are executed.

Parsing finishes just like when we put the script at the end of the body tag, but overall the script execution finishes well before, because the script has been downloaded in parallel with the HTML parsing.

So this is the winning solution in terms of speed

Did you find this article valuable?

Support Arun Kumar by becoming a sponsor. Any amount is appreciated!