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