DEV Community

Priyanka Sarode
Priyanka Sarode

Posted on

async and defer in <script> tag

This question asked in the interview to test whether you know different JavaScript files loading strategies or not and their behavior.

Let's understand its behavior and when to use.

  • Basically both async and defer are boolean attributes which are used in script tag to load external (e.g. bootstrap.js) JavaScript files in to our web page.
  • When we load the page, two things happened:
  1. html parsing
  2. loading of JavaScript files - also contains 2 parts

a) fetching/ downloading script file from the network/ server
b) execution of that file line by line

Now we will look into different scenarios where both the keywords used in script tag

1) script tag in Head element where no async and defer used (Normal flow)
script tag in Head

<!DOCTYPE html>
<html>
  <head>
    <script src="./script.js"></script>
  </head>
  <body>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

Here when the html page loads in the browser, it starts html parsing from top to bottom line by line. If it finds the script tag, html parsing is paused, a request is sent to the server to get the script and script file starts downloading. Once download completes, script file starts executing. After this, browser starts parsing the rest of the html page.

Limitation of this approach:
Sometimes size of the script file is larger, in this case processing time will be longer. And this increases the load time of the page and restricts the user to navigate through other pages of the website. To solve this problem, async and defer attributes come into play.

2) script tag in bottom of the body and no async and defer is used

script tag in body

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <script src="./script.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Here browser starts html parsing from top and once html parsing finished, then only script fetching starts. After completing fetching, script execution starts till end.

This is far better approach than the previous ones. But for long HTML documents, there may be a noticeable delay for people who are using slow internet.

3) script tag in head and async is used

script in head with async

<!DOCTYPE html>
<html>
  <head>
    <script async src="./script.js"></script>
  </head>
  <body></body>
</html>
Enter fullscreen mode Exit fullscreen mode

Here html parsing and script fetching continue in parallel. Once script fetching done, html parsing paused and script execution starts till end. After this html parsing resumes and loads the rest of the page.

This approach is useful when there are multiple third party scripts (google ads, analytics etc.) which are independent of each other and doesn't have direct relationship with DOM.
And they will execute as soon as they finish downloading, regardless of their order in the code means browser doesn't guarantee the order of execution of scripts.

4) script tag in head and defer is used

script in head with defer

<!DOCTYPE html>
<html>
  <head>
    <script defer src="./script.js"></script>
  </head>
  <body></body>
</html>
Enter fullscreen mode Exit fullscreen mode

Like async, here also html parsing and script fetching continue in parallel. After fetching of script completes, browser keep that file aside means doesn't execute instantly. Once the html parsing finished, then only script execution starts till end.

This approach is useful when you want html dom should be load first and then other dependent scripts. Also here scripts are executed in the order the way they are defined in the code.

Similarity

  • Both async and defer are boolean attributes
  • If script tag has no src property, then defer and async attributes will be ignored by browser hence no effect on the page loading
  • Both allow the browser to continue html parsing and script fetching to be done in parallel

Difference

async defer
execution when loaded, script files executes immediately it doesn't execute immediately after loading
execution order execution in no particular order execution in order
dependency used when script files are not dependent on each other used when scripts are dependent on each other
blocking before executing, browser blocks html parsing it doesn't block html page
DOM interaction use when don't need to interact with the DOM use when interact with the DOM

Tricky Question

What will happen if I put script tag in the bottom of the body with defer attribute?
Ans - As we know, defer attribute delaying the execution of the script.
When we use defer at the bottom of the body, entire html parsing is already completed, so any way that script will execute later on. So it doesn't have any effect on the page. It is similar to no defer tag.
defer attribute is useful when we use in the script tag in the head section. And we want execution to be happened later.

Top comments (2)

Collapse
 
nevodavid profile image
Nevo David

yeah i always mix these up but finally makes sense now - love little things like this that save time down the line. you ever run into a situation where mixing async and defer actually broke something?

Collapse
 
priyanka_sarode_694e69474 profile image
Priyanka Sarode • Edited

Thank you Nevo.
Not yet...