What is the difference between the Async and Defer Script attribute ?

About

The script HTML element has two asynchronous loading method that may be chosen via the presence of the async or defer attribute.

Async and defer are resource fetch instructions.

Usage

In a page load, the following processing occurs:

Type Usage Example Processing
Inline / No Async/Defer The script runs during parsing analytics scripts The browser runs the code, blocking the parser
Async The script should run as soon as possible The browser downloads the script asynchronously while it continues to parse the HTML document. When the script finishes downloading, parsing is blocked while the script executes.
Defer The script runs after the parsing A video player The browser downloads the script asynchronously while it continues to parse the HTML document. The script doesn't run until the parsing is complete and before the DOMContentLoaded event

Why defer scripts may run before async scripts ?

You can see in the code demo that defer scripts are executed before the async scripts.

This is generally the case because defer blocks the DOMContentLoaded event and has therefore a higher priority in the queue of script to run.

Visualization

The below diagram summarize how the user-agent (browser) will execute the HTML page:

1)

where:

Blocking

An async or defer script will execute before the page load event. They block it in some way. If you don't want this behavior, you should preload them and use/load them in your script when needed.

Because of that, they also have an impact on the largest content full paint

Code Demo

This demo shows you the event in order that occurs related to the code.

Note that because this is difficult to simulate a slow parsing, the defer and async script ends up in the execution queue together.

In this case, the defer script has a higher priority because it blocks the DOMContentLoaded event and its runs then first.

  • The defer script that will be loaded with the defer attribute
console.log("Hello from 'defer' script");
  • The async script that will be loaded with the async attribute
console.log("Hello from 'async' script");
  • The HTML page that:
    • loads the script (described above)
    • execute inline javascript (this code will be called first)
<script>console.log('[1]: DOM is build')</script>
<script defer src="/_export/code/web/html/script_async_vs_defer?codeblock=0"></script>
<script async src="/_export/code/web/html/script_async_vs_defer?codeblock=1"></script>
<script>
console.log('[2]: Inline Wait Script is started');
let nowInline = new Date().getTime(), endInline = nowInline ;
while(endInline < nowInline + 3000) { endInline = new Date().getTime(); };
console.log('[3]: Inline Wait Script had ended');
</script>
<script>console.log('[4]: Lena is downloading');</script>
<img src="/_media/lenna.png" width="200px"/>
<script>console.log('[5]: Lena has been downloaded');</script>
<script>console.log('[4]: DOM was parsed')</script>
<script>window.addEventListener("load", () =>  console.log("page load event fired") )</script>
  • Output:

Powered by ComboStrap