loading...
Cover image for Async vs. Defer JS Functions

Async vs. Defer JS Functions

connoro7 profile image Connor Dillon ・3 min read

Javascript is a "parser blocking resource," meaning an HTML document is blocked from parsing by the fetching and execution of Javascript.

Normal Parsing

By default, as mentioned above, JavaScript files will interrupt the parsing of the HTML document in order for them to be fetched (if not inline) and executed.

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

Take, for example, this script element located somewhere in the middle of the page. As the document parser goes through the page, this is what occurs:

Alt Text

Async Parsing

The async attribute is used to indicate to the browser that the script file can be executed asynchronously. The HTML parser does not need to pause at the point it reaches the script tag to fetch and execute, the execution can happen whenever the script becomes ready after being fetched in parallel with the document parsing.
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.

⛔️ Don't use async and defer attributes for scripts that depend on each other or need to load in a specific order.

<script async src="script.js">

Alt Text

Defer Parsing

The defer attribute tells the browser to only execute the script file once the HTML document has been fully parsed. Like an asynchronously loaded script, the file can be downloaded while the HTML document is still parsing. However, even if the file is fully downloaded long before the document is finished parsing, the script is not executed until the parsing is complete.

⛔️ Don't use async and defer attributes for scripts that depend on each other or need to load in a specific order.

<script defer src="script.js">

Alt Text

Which Should You Use?

⛔️ Don't use async and defer attributed for scripts that depend on each other or need to load in a specific order.

Where is the <script> element located?

Asynchronous and deferred execution of scripts are more important when the <script> element is not located at the very end of the document. HTML documents are parsed in order, from the first opening <html> element to its close. If an externally sourced JavaScript file is placed right before the closing </body> element, it becomes much less pertinent to use an async or defer attribute. Since the parser will have finished the vast majority of the document by that point, JavaScript files don't have much parsing left to block.

Is the script self-contained?

For script files that are not dependent on other files and/or do not have any dependencies themselves, the async attribute is particularly useful. Since we do not care exactly at which point the file is executed, asynchronous loading is the most suitable option.

Does the script rely on a fully parsed DOM?

In many cases, the script file contains functionality that requires interaction with the DOM. Or, it may have a dependency on another file included on the page. In these cases, the DOM must be fully parsed before the script should be executed. Typically, such a file will be placed at the bottom of the page to ensure everything before it has been parsed. However, in situation where, for whatever reason, the file in question needs to be placed elsewhere, the defer attribute can be used.

Is the script a (small) dependency?

Finally, if the script is relatively small, and/or is depended on by other files, it may be more useful to have it defined inline. Although having it inline will block the parsing of the HTML document, it should not be a significant interference if it's a small size. Additionally, if it is depended on by other files, the minor blocking may be necessary.

Discussion

pic
Editor guide