JS: Load Order, defer, async, module
When a JavaScript appears in a HTML page:
<script src="some.js"></script>
or
<script>x=3;</script>
the browser will fetch and execute the script right away, and wait for it to finish, before loading any HTML that appear after the script tag.
This means:
- If your JavaScript manipulate the page's HTML elements that's below the script, it'll fail because those element are not loaded yet.
- If your JavaScript is slow, user will see the browser freeze, showing no content after the script, until the script execution is finished.
Old solution (2005) is to always place your JavaScript at the bottom of the page, right before the </body>
tag. But this is not a good solution today.
defer Load
You can use the attribute defer
like this:
<script defer src="file.js"></script>
defer
means run script after the page finished parsing.
🛑 WARNING:
There is no =true
or =false
after async
or defer
.
🛑 WARNING:
When using defer
or async
, you must have a src=val
. You cannot use it like this:
<script defer>code</script>
.
That'll behave the same as without defer/async.
As of 2013-07-11, all major browser support defer
.
The execution order of multiple defer scripts, is the order they appear on HTML page.
async Load
async
(asynchronous) means run the script and continue loading the HTML page at the same time.
<script async src="file.js"></script>
🛑 WARNING:
with async
, your script will not see HTML elements that are below the script tag, because they are not loaded yet.
If both async
and defer
are specified, it behaves as if only defer
is specified.
The execution order of multiple async scripts is not specified. (not guaranteed to be in the order on the page.)
As of 2013-07-11, all major browser support async
.
Module Script Load Order
When
type="module"
script is used, it loads like
defer
.
Optionally you can specify
async
loading.
〔see Import/Export〕
Deferred Loading JavaScript for Old Browser
window.onload
An old way to load script (used before ~2010), is to use the window.onload
event.
This is not a good solution, because it waits until all images and iframes finished downloading too.
You'll see old code like this:
function f1 () {console.log( "f1 called");}; function f2 () {console.log( "f2 called");}; window.onload = function(){ f1(); f2(); };