Efficiently load script file in javascript using Async and Defer

Efficiently load script file in javascript using Async and Defer

Nowadays, optimizing your web page is crucial in many aspects. As in modern websites, scripts are heavier than HTML, their download size is larger & processing time is also longer. This results in the slow loading of your web page. If the webpage loads slow, the search engines will rank it low in the search index & this will lead to fewer users on the site. So the users, probably won't come back to a web page that takes minutes to load the information.

When the browser is loading HTML & comes across a script file either external or internal. It pauses the DOM creation & executes the script file or fetches it then executes (if external). This blocks the rending of the page & users will feel that site is slow specifically if they have a low internet connection. There's a workaround to fix this issue is by adding script tags on the bottom of your body element. But this isn't the perfect solution for all use cases, consider when the content of the body tag is loaded & the user starts interacting with the page but the script isn't loaded yet. Luckily there are two attributes of script tag which are async and defer to fix this render-blocking issue to a good extent. But both the attributes only work for external javascript.

Defer:

The defer attribute tells the browser to not wait for the script instead continue building HTML page, the script will be loaded parallelly & will be executed only after full DOM is built.

defer.png

So, as with defer, it executes only after parsing HTML content, which means this doesn't block the rendering of HTML files. The script here gets executed after DOM is ready but before DOMContentLoaded event.

<p> ... content before script ...</p>
// this script will run on DOM content load
<script>document.addEventListner("DOMContentLoaded", () => {})</script>
// this script will run after Dom is ready but before DOM content load
<script defer src=""></script>

In the above example, the Html page gets loaded first then the script with the event listener waits for defer script to get downloaded then only it executes.

Also, all scripts with defer attributes keep their order relative to the way they are positioned in file.

<script defer src="longerfilesize.js"></script>
<script defer src="smallfilesize.js"></script>

Here, both scripts will be downloaded parallelly when the browser is parsing HTML file. smaller will be downloaded first but as defer they get executed after Dom is ready. So the smaller one will wait for html parsing & also it will wait for the execution of the larger one as they follow relative order.

Async

The Async attribute tells the browser that script is completely independent. So, it can be executed asynchronously. The HTML parser doesn't need to pause the parsing when it reaches the script tag with async attribute. This script can also be downloaded parallelly just like script with defer attribute. But the execution of this script can happen whenever it is ready after being fetched parallelly during HTML parsing.

async.png This attribute is only available for externally located script files. When an external script has this attribute, the file can be downloaded while the HTML document is still parsing. Once it has been downloaded, the parsing is paused for the script to be executed.

Just like script with defer both scripts files will be downloaded parallelly but as they are independent of each other. so whichever gets downloaded first will execute by pausing HTML parsing . so, we can say that in async scripts gets downloaded in the background and run when ready. The DOM and other scripts don’t wait for them, and they don’t wait for anything. A fully independent script that runs when loaded.

<p>...content before scripts...</p>

<script>
  document.addEventListener('DOMContentLoaded', () =>{});
</script>

<script async src="largerFileSize.js"></script>
<script async src="smallerFileSize.js"></script>

In above code, page content shows up immediately: async doesn’t block it. DOMContentLoaded may happen both before and after async, no guarantees here. A smaller script goes second, but probably loads before long.js, so small.js runs first. Although, it might be that long.js loads first, if cached, then it runs first. In other words, async scripts run in the “load-first” order.

Async scripts are great when we integrate an independent third-party script into the page: counters, ads and so on, as they don’t depend on our scripts, and our scripts shouldn’t wait for them.

So, what's the best one?

It depends!

I know, it's the kind of answer that you'll find everywhere if you ask yourself this question. You need to know that neither async nor defer guarantees non-blocking the rendering as at the end of all, it is up to you and your script.

Well, implementing either async or defer will make your loading times automatically better than before (if implemented properly). It behaves quite optimal on slow networks.

Summary

image.png

The scripts marked with defer are executed right after the domInteractive event, which happens after the HTML is loaded, parsed and the DOM is mounted. Once this is done, the browser will emit the domComplete event, and then onLoad. Async and defer are basically two boolean attributes for the