Javascript defer and async attributes, what they are, how and when to use them.
What does it mean to defer a javascript?
When you defer JavaScript in an HTML document, it means that you are instructing the browser to execute the JavaScript code after the HTML has been completely parsed. This is done by using the defer
attribute in the <script>
tag. By default, without the defer
attribute, the browser will stop parsing the HTML as soon as it encounters a <script>
tag to download and execute the JavaScript. This can slow down the rendering of the page as the browser waits for the script to download, parse, and execute.
The defer
attribute ensures that scripts are executed in the order they appear in the HTML document. It is a boolean attribute, meaning you don’t need to set a value for it. You just need to include it in the script tag. For example:
<script defer src="script1.js"></script>
<script defer src="script2.js"></script>
In this case, script1.js
will execute first, followed by script2.js
, and both will run after the HTML is completely parsed.
Using defer
can help improve the performance of your web page as it allows the HTML content to be displayed to the user faster. This can be particularly beneficial for pages that rely on a lot of JavaScript.
How does javascript load if I have some with the defer attribute and some without?
When you have multiple JavaScript files in an HTML document, some with the defer
attribute and some without, the browser handles them differently.
- Scripts without the
defer
attribute: As soon as the browser encounters a<script>
tag without thedefer
attribute, it stops parsing the HTML, downloads the JavaScript file (if it has thesrc
attribute), executes it, and then continues parsing the HTML. This is called a “blocking” script because it stops the HTML parsing process and can delay the rendering of the web page. - Scripts with the
defer
attribute: The browser downloads the script file while continuing to parse the HTML. The script will only be executed after the HTML has been completely parsed.
Here is an example:
<script src="script1.js"></script>
<script defer src="script2.js"></script>
<script src="script3.js"></script>
<script defer src="script4.js"></script>
Here is how the scripts will load:
- The browser encounters
script1.js
without thedefer
attribute, so it stops parsing the HTML, downloads and executes the script, and then continues parsing the HTML. - The browser encounters
script2.js
with thedefer
attribute, so it downloads the script while continuing to parse the HTML. The script execution is deferred until the HTML is completely parsed. - The browser encounters
script3.js
without thedefer
attribute, so it stops parsing the HTML again, downloads and executes the script, and then continues parsing the HTML. - The browser encounters
script4.js
with thedefer
attribute, so it downloads the script while continuing to parse the HTML. The script execution is deferred until the HTML is completely parsed.
When the HTML parsing is completed:
script2.js
will execute first because it was encountered beforescript4.js
.- After
script2.js
finishes executing,script4.js
will execute.
The key takeaway is that scripts with the defer
attribute will always execute in the order they appear in the HTML document, but after the HTML parsing is completed. Scripts without the defer
attribute will execute as soon as they are encountered, blocking the HTML parsing.
So when do I use defer and when shouldn’t I use defer?
When to use defer
:
- When your script depends on the complete DOM: If your script relies on the full HTML document being available (for example, it needs to manipulate elements or attach event listeners), you should use
defer
. The script will only run after the HTML is completely parsed. - When order matters: If you have multiple script files that need to be executed in a specific order, use
defer
for all of them. They will be executed in the order they appear in the HTML document. - For performance: If you have a large script that doesn’t need to run immediately, using
defer
can help speed up the initial page load time. The browser will continue parsing and displaying the HTML while the script is being downloaded, which can provide a better user experience.
When not to use defer
:
- When your script doesn’t depend on the DOM: If your script doesn’t interact with the HTML document (e.g., a web worker or a script that sends data to an analytics service), you might not need to use
defer
. - When your script needs to run as soon as possible: If you have a script that needs to run immediately (for example, a script that sets up a user interface feature that should be available as soon as the page starts loading), you might not want to use
defer
. - Inline scripts: The
defer
attribute only works with external scripts (those loaded with thesrc
attribute). If you have an inline script (a script directly written in the HTML document), thedefer
attribute won’t have any effect. - Older browsers: If you need to support older browsers that don’t recognize the
defer
attribute, you might want to use alternative approaches to control the execution order of your scripts, like placing the script tags right before the closing</body>
tag.
In summary, use defer
when you have scripts that depend on the full DOM, when you want to improve performance, or when order matters. Avoid using defer
for scripts that don’t interact with the DOM, need to run immediately, or in cases where you’re dealing with inline scripts or older browsers.
Ok, so what about async then?
async
is another attribute you can use in the <script>
tag, similar to defer
. It also allows you to control the execution of JavaScript files, but it behaves differently.
Here’s how the async
attribute works:
- When the browser encounters a
<script>
tag with theasync
attribute, it downloads the script file asynchronously while continuing to parse the HTML. - Unlike
defer
, the script will execute as soon as it finishes downloading, regardless of where the browser is in the parsing process.
Here’s an example:
<script async src="script1.js"></script>
<script async src="script2.js"></script>
<script async src="script3.js"></script>
In this case, the scripts will be downloaded in parallel, and each script will execute as soon as it’s downloaded. The order of execution is unpredictable, as it depends on the download speeds of each script. If script2.js
finishes downloading first, it will execute before script1.js
and script3.js
.
When to use async
:
- For independent scripts: If you have a script that doesn’t depend on the DOM or other scripts (e.g., an analytics script), you can use
async
. It will be downloaded in parallel and run as soon as it’s ready, without affecting the rest of the page. - To speed up page load time: If your script doesn’t need to wait for the DOM or other scripts, using
async
can help speed up the page load time, as the script will be downloaded and executed without blocking the HTML parsing.
When not to use async
:
- When order matters: If you have multiple scripts that need to be executed in a specific order, avoid using
async
, as it makes the execution order unpredictable. - When your script depends on the DOM: If your script relies on the full HTML document being available, it might not work as expected with
async
, as it could run before the DOM is ready. - Inline scripts: Similar to
defer
, theasync
attribute only works with external scripts (those loaded with thesrc
attribute).
So, use async
when you have independent scripts that don’t depend on the DOM or other scripts and when you want to improve page load time. Avoid using async
when the execution order matters, your script relies on the DOM, or you’re dealing with inline scripts.
In Summary
Both async
and defer
are attributes used in the <script>
tag to control the execution of JavaScript files. With async
, the script is downloaded in parallel with the HTML parsing and executed as soon as it finishes downloading, which can occur before or after the HTML is completely parsed. The execution order of multiple async
scripts is unpredictable. With defer
, the script is also downloaded in parallel but is guaranteed to execute only after the HTML is fully parsed and in the order they appear in the HTML document. In essence, async
is suitable for independent scripts where execution order doesn’t matter, while defer
is used when the scripts depend on the full DOM or need to execute in a specific order.