Scripts : async and defer in Javascript

Radheshyam Kumar
4 min readJul 16, 2022

--

Hey folks, in this article you will get to know about async and defer script attributes, what are they and why we use them , all these queries will get resolved at the end. So let’s start, first let me ask you a question :

What happens when a browser loads a website HTML and <script>…</script> tag on it ?

Answer is that , when a browser loads HTML and as soon as it comes across a <script>...</script> tag then it has to discontinue buiding the DOM .Then it must execute the script right now and then it process the rest of the page. If there is external script <script src="...">...</script> then the browser waits for the script to get download then execute the downloaded script and then only process the rest of page.

So if we write steps for that it would be like this:

(i) Browser fetches the HTMLpage
(ii) Begin parsing the HTML (e.g index.html)
(iii) As soon as script tag is encountered (say external script file) then HTML parsing is paused then and there (i.e parser blocks and stops parsing the other HTML on page)
(iv) Browser sends request to server to get script file
(v) After sometime when scripts get downloaded as well as executed
(vi) Then again parser continues parsing rest of HTML document.

What are the issues ?

There are two issues associated with it:
(a) It cause the bad user experience because if bulky script is at the top of page which has larger size then it blocks the page and users can’t see the page content untill all scripts get downloaded and executed. So loadtime of page increases.

Suppose in above example scripts take 10 sec to downlaod and execute . So at first “content before script” will be visible then script tag is encountered, so it will first download script file and execute which took 10 sec , then only (i.e, after 10sec) “content after script” will be visible.

(b) If scripts are at the top or anywhere in the middle then they can’t see the DOM elements below them. So they can’t add handlers etc.

One solution to this problem is that we can put all scripts at bottom of page , then they can see the DOM elements above it , But this is not a perfect solution if there is a large HTML documents then there may be some noticable delay.

Now async and defer attributes come into picture. Note here, both attributes are only for external scripts. attribute is ignored if the <script> tag has no src.

async (Asynchronous)

When we use async attribute the script is downloaded asynchronously with rest of page without pausing the HTML parsing. Once script is downloaded , then parsing will be paused and scripts execution will happen. Once execution is done HTML parsing will then resume.

In other words we can say that , scripts load in the background and run when ready. DOMContentLoaded and async scripts don’t wait for each other.

DOMContentLoaded may happen :-
(i) before an async script (if an async script has larger size and finishes loading after the page is complete)
(ii) after an async script (if an async script is small or stored in cache)

One most important thing to note here is that if there are two or more scripts with async attribute , then they don’t wait for each other. Whatever loads first will execute first.In other words, async scripts run in the “load-first” order.

See above code, smaller scriptsmall.js is in second but probably loads before long.js sosmall.js will runs first.

defer (Deferred)

  • Scripts with defer never block the page and always execute when the DOM is ready (but before DOMContentLoaded event).

The defer attribute tells the browser not to interfere with the HTML parsing and only to execute the script file once HTML document has been fully parsed.

When script with defer attribute is encountered , the downloading of scripts starts asynchronously in background & get downloaded but execute only after HTML parsing finished .

Suppose a page has two deferred scripts: the long.js and then small.js.
What you think which will be executed first ?? Both the scripts will starts downloading in parallel in background. small.js being smaller downloaded first . But, it will not execute first because defer atrribute ensures that relative order is kept. So although small.js got download first it stil waits and runs after long.js get downloaded and executed.
In other words, scripts will execute in same order as they are in the page.

Hope it will help 👏👏👏👏.

--

--