+1-650-731-2358 | john@johnshipp.com | Skype: shippjohn

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.

  1. Scripts without the defer attribute: As soon as the browser encounters a <script> tag without the defer attribute, it stops parsing the HTML, downloads the JavaScript file (if it has the src 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.
  2. 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:

  1. The browser encounters script1.js without the defer attribute, so it stops parsing the HTML, downloads and executes the script, and then continues parsing the HTML.
  2. The browser encounters script2.js with the defer attribute, so it downloads the script while continuing to parse the HTML. The script execution is deferred until the HTML is completely parsed.
  3. The browser encounters script3.js without the defer attribute, so it stops parsing the HTML again, downloads and executes the script, and then continues parsing the HTML.
  4. The browser encounters script4.js with the defer 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 before script4.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:

  1. 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.
  2. 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.
  3. 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:

  1. 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.
  2. 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.
  3. Inline scripts: The defer attribute only works with external scripts (those loaded with the src attribute). If you have an inline script (a script directly written in the HTML document), the defer attribute won’t have any effect.
  4. 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:

  1. When the browser encounters a <script> tag with the async attribute, it downloads the script file asynchronously while continuing to parse the HTML.
  2. 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:

  1. 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.
  2. 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:

  1. 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.
  2. 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.
  3. Inline scripts: Similar to defer, the async attribute only works with external scripts (those loaded with the src 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.