The interviewer might start with asking you questions around how do you load a script on a webpage. The discussion would generally lead to questions around defer vs async.

Before we jump onto the difference between defer and async, there are a few concepts that we should be clear on. These are discussed below:

HTML Parsing

When the browser receives an HTML document from the server, the first thing it does is start reading the HTML or in more technical terms, it starts parsing the HTML. The end result of parsing is the DOM (Document Object Model). For the page to be visible to the user, it's important that the DOM is ready as soon as possible.

Phases of Script Loading

There are two important phases of script loading:

Script download

A script download happens when the browser makes a network request to fetch a javascript file. Download is an expensive operation. It contributes to the majority of the time taken to render a page.

Script execution

Script execution happens after the file has downloaded. The Javascript engine is responsible for executing the javascript.

A good understanding of how external Javascript files are loaded on a webpage is required. Here are the most popular ways to do so:

In the head (without async or defer)

<head>
    <script src="script.js"></script>
</head>

This is the most traditional way of loading scripts on the webpage. While parsing, when this line is encountered, the browser stops parsing, makes a request to get the javascript file. And once the javascript file has downloaded, it is executed. Only after that point, the browser can resume back HTML parsing.

Moreover, the script might try to access a DOM element that is not yet available, thus resulting in an error. This problem can however be avoided by using DOMContentLoaded as shown below. In this case, the execution will happen only after the DOM parsing has completed.

window.addEventListener('DOMContentLoaded', (event) => {
  // Javascript goes here
});

At the end of the body (without async or defer)

<body>
    <!-- Document body markup -->
    <script src="script.js"></script>
</body>

This method of loading scripts makes sure HTML parsing has almost finished and the DOM is available to interact with before any javascript code can be executed. When a script tag is encountered at the end of body, a network request to the javascript file is made. Once, it's available, the script is executed.

With async

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

When async attribute is used with the script, downloading of the script does not block HTML parsing. The download will happen in parallel in a separate thread. However, when the script has downloaded, HTML parsing will be blocked in the favour of script execution. The window load event is not fired until the async scripts have executed.

With defer

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

defer attribute is similar to async in the sense that the script download happens in parallel to parsing. However, a deferred script executes only when the DOM is ready but before DOMContentLoaded has fired. DOMContentLoaded is not fired until the script has executed.

The below image makes the difference clear between the four ways of loading scripts.

Popular ways to load external javascript

It's clear that async and defer are definitely faster than the traditional ways due to parallel script download.

Now coming back to the actual discussion - the difference between defer and async in javascript.

Defer vs Async

defer and async both download the script in parallel to HTML parsing. However, there are two major differences between the two:

  • Deferred scripts are executed only after the DOM is ready. Async scripts on the other hand run as soon as they are available.
  • Deferred scripts preserve the order in which they occur in the HTML document. Async scripts, however, don't preserve the order. The script that downloads first, executes first.
  • Deferred scripts prevent window DOMContentLoaded event from firing until the script has executed. Async scripts prevent the window load event from firing until executed.

When to use defer and async

defer should generally be used when the order of script execution matters - one of your scripts being dependent on other script. defer should also be used when your script needs the DOM to be ready.

async can be used when the script is pretty independent and the sequence does not matter. async should not be used if your script needs to interact with the DOM, because it might execute before the DOM is even ready. However, this requirement can be ignored using load listeners like DOMContentLoaded or load.


I hope the explanation for this javascript interview question - 'defer vs async' was helpful. Don't forget to subscribe below for more questions like this. You can also like us on facebook and receive latest updates.