Async vs Defer in Javascript

Async vs Defer in Javascript

Introduction

How many times have you added javascript to your HTML like this <script src="path/to/some/javascript"></script> but have you ever pondered how browser handle that line of code? Why do we sometimes pass async or defer attributes to the script tag?

In this article, we'll take a look and understand major differences between async and defer attributes and which one is better to use. But first, let's understand what if we don't use them at all.

<script> tag without async or defer

Let's take a look at the following code.

<html lang="en">
  <head>
    <title>Async vs Defer</title>
    <script src="path/to/some/javascript"></script>
  </head>
  <body>
    <h1>Async vs Defer</h1>
  </body>
</html>

When the browser runs this file it starts by parsing the HTML line by line. In this example, as soon as the browser sees the script tag, it stops the HTML parsing and starts to fetch the javascript file and it also executes the javascript line by line immediately after it fetches the javascript file.

without-using-async-or-defer-in-script-tag.png

During this fetching of the javascript file, the HTML parsing is stopped and this delays the content rendering on DOM and eventually slows down the website. This is not a good thing because if you are working on a large project then even a delay of say 1 second might lead people to go back from your website and eventually hurt the revenue.

We can solve this by using async or defer so let's take a look at them.

Async Attribute

<script async src="path/to/some/javascript"></script>

When we use the async attribute in a script tag. The browser starts by parsing the HTML file and when the browser sees the script tag it starts fetching the javascript in the background while continuing the HTML parsing. Once the script is available to be executed then the browser stops the HTML parsing and executes the Javascript file line by line. Once the javascript execution finishes the browser continues the HTML parsing.

using-async-in-script-tag.png

Defer Attribute

<script defer src="path/to/some/javascript"></script>

The defer attribute is quite similar to async. The one difference is that the scripts loaded with defer attribute are not executed until HTML parsing is completely finished. What that means is browsers start by parsing HTML and fetches the javascript in the background if it encounters any script tags and continues the HTML parsing. Javascript is executed only after the HTML is completely parsed.

using-defer-in-script-tag.png

Problem with async

If multiple scripts are being used in HTML file and some are dependent on others, so in order for them to work correctly, we need to make sure that the script on which others are dependent are loaded and executed first in the browsers before the script which is dependent on this script.

The async attribute does not guarantee the order in which different javascript files are executed.

Let's take an example,

<script async src="script-1"></script>
<script async src="script-depended-on-script-1"></script>
<script async src="script-depended-on-script-above-this"></script>

If we use async in this case then it does not guarantee that script-1 will be loaded and executed before the script-depended-on-script-1 because these scripts are being fetched in the background and one might be fetched before the others due to any reason, like its size or network issue. So if script-depended-on-script-1 is fetched first then it will be executed first because when using async attribute browsers execute the javascript immediately after it is available or downloaded in the browsers.

  • defer however guarantees that scripts will be executed in the order even if one is available to the browser before the other because all scripts will be executed after the HTML parsing is done.

Conclusion

  • If you have multiple scripts that are dependent on each other then use defer as it guarantees the order of execution.
  • If you don't want to block the HTML parsing then use defer
  • I personally recommend using defer most of the time.

I hope you found this interesting and learned something. Thank you.

Per Aspera Ad Astra