How exactly does <script defer="defer"> work? - javascript

I have a few <script> elements, and the code in some of them depend on code in other <script> elements. I saw the defer attribute can come in handy here as it allows code blocks to be postponed in execution.
To test it I executed this on Chrome: http://jsfiddle.net/xXZMN/.
<script defer="defer">alert(2);</script>
<script>alert(1)</script>
<script defer="defer">alert(3);</script>
However, it alerts 2 - 1 - 3. Why doesn't it alert 1 - 2 - 3?

A few snippets from the HTML5 spec: http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async
The defer and async attributes must
not be specified if the src attribute
is not present.
There are three possible modes that
can be selected using these
attributes [async and defer]. If the async attribute is
present, then the script will be
executed asynchronously, as soon as it
is available. If the async attribute
is not present but the defer attribute
is present, then the script is
executed when the page has finished
parsing. If neither attribute is
present, then the script is fetched
and executed immediately, before the
user agent continues parsing the page.
The exact processing details for these
attributes are, for mostly historical
reasons, somewhat non-trivial,
involving a number of aspects of HTML.
The implementation requirements are
therefore by necessity scattered
throughout the specification. The
algorithms below (in this section)
describe the core of this processing,
but these algorithms reference and are
referenced by the parsing rules for
script start and end tags in HTML, in
foreign content, and in XML, the rules
for the document.write() method, the
handling of scripting, etc.
If the element has a src attribute,
and the element has a defer attribute,
and the element has been flagged as
"parser-inserted", and the element
does not have an async attribute:
The element must be added to the end of the list of scripts that will
execute when the document has finished
parsing associated with the Document
of the parser that created the
element.

The real answer is: Because you cannot trust defer.
In concept, defer and async differ as follows:
async allows the script to be downloaded in the background without blocking. Then, the moment it finishes downloading, rendering is blocked and that script executes. Render resumes when the script has executed.
defer does the same thing, except claims to guarantee that scripts execute in the order they were specified on the page, and that they will be executed after the document has finished parsing. So, some scripts may finish downloading then sit and wait for scripts that downloaded later but appeared before them.
Unfortunately, due to what is really a standards cat fight, defer's definition varies spec to spec, and even in the most recent specs doesn't offer a useful guarantee. As answers here and this issue demonstrate, browsers implement defer differently:
In certain situations some browsers have a bug that causes defer scripts to run out of order.
Some browsers delay the DOMContentLoaded event until after the defer scripts have loaded, and some don't.
Some browsers obey defer on <script> elements with inline code and without a src attribute, and some ignore it.
Fortunately the spec does at least specify that async overrides defer. So you can treat all scripts as async and get a wide swath of browser support like so:
<script defer async src="..."></script>
98% of browsers in use worldwide and 99% in the US will avoid blocking with this approach.
(If you need to wait until the document has finished parsing, listen to the event DOMContentLoaded event or use jQuery's handy .ready() function. You'd want to do this anyway to fall back gracefully on browsers that don't implement defer at all.)

UPDATED: 2/19/2016
Consider this answer outdated. Refer to other answers on this post for information relevant to newer browser version.
Basically, defer tells the browser to wait "until it's ready" before executing the javascript in that script block. Usually this is after the DOM has finished loading and document.readyState == 4
The defer attribute is specific to internet explorer. In Internet Explorer 8, on Windows 7 the result I am seeing in your JS Fiddle test page is, 1 - 2 - 3.
The results may vary from browser to browser.
http://msdn.microsoft.com/en-us/library/ms533719(v=vs.85).aspx
Contrary to popular belief IE follows standards more often than people let on, in actuality the "defer" attribute is defined in the DOM Level 1 spec http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html
The W3C's definition of defer: http://www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer:
"When set, this boolean attribute provides a hint to the user agent that the script is not going to generate any document content (e.g., no "document.write" in javascript) and thus, the user agent can continue parsing and rendering."

defer can only be used in <script> tag for external script inclusion. Hence it is advised to be used in the <script>-tags in the <head>-section.

As defer attribute works only with scripts tag with src. Found a way to mimic defer for inline scripts. Use DOMContentLoaded event.
<script defer src="external-script.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
// Your inline scripts which uses methods from external-scripts.
});
</script>
This is because, DOMContentLoaded event fires after defer attributed scripts are completely loaded.

The defer attribute is only for external scripts (should only be used if the src attribute is present).

Have a look at this excellent article Deep dive into the murky waters of script loading by the Google developer Jake Archibald written in 2013.
Quoting the relevant section from that article:
Defer
<script src="//other-domain.com/1.js" defer></script>
<script src="2.js" defer></script>
Spec says: Download together, execute in order just before DOMContentLoaded. Ignore “defer” on scripts without “src”.
IE < 10 says: I might execute 2.js halfway through the execution of 1.js. Isn’t that fun??
The browsers in red say: I have no idea what this “defer” thing is, I’m going to load the scripts as if it weren’t there.
Other browsers say: Ok, but I might not ignore “defer” on scripts without “src”.
(I'll add that early versions of Firefox trigger DOMContentLoaded before the defer scripts finish running, according to this comment.)
Modern browsers seem to support async properly, but you need to be OK with scripts running out of order and possibly before DOMContentLoaded.

Should be also noted that there might be problems in IE<=9 when using script defer in certain situations. More on this: https://github.com/h5bp/lazyweb-requests/issues/42

<script defer> -
As soon as the browser interacts with the script tag with defer
It starts fetching the script file while also parsing the HTML side-by-side.
In this case, the script is only executed once the HTML parsing is completed.
<script async> —
As soon as the browser interacts a script tag with async
It starts fetching the script file while parsing the HTML side-by-side.
But stops the HTML parsing when the script is completely fetched, after which it starts executing the script, post which the HTML parsing continues.
<script> —
As soon as the browser interacts with a script tag
It stops the parsing of HTML, fetches the script file,
In this case, executes the script, and then continues the parsing of HTML.

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed. Since this feature hasn't yet been implemented by all other major browsers, authors should not assume that the script’s execution will actually be deferred. Never call document.write() from a defer script (since Gecko 1.9.2, this will blow away the document). The defer attribute shouldn't be used on scripts that don't have the src attribute. Since Gecko 1.9.2, the defer attribute is ignored on scripts that don't have the src attribute. However, in Gecko 1.9.1 even inline scripts are deferred if the defer attribute is set.
defer works with chrome , firefox , ie > 7 and Safari
ref: https://developer.mozilla.org/en-US/docs/HTML/Element/script

The defer attribute is a boolean attribute.
When present, it specifies that the script is executed when the page has finished parsing.
Note: The defer attribute is only for external scripts (should only be used if the src attribute is present).
Note: There are several ways an external script can be executed:
If async is present: The script is executed asynchronously with the rest of the page (the script will be executed while the page continues the parsing)
If async is not present and defer is present: The script is executed when the page has finished parsing
If neither async or defer is present: The script is fetched and executed immediately, before the browser continues parsing the page

Related

Google Analytics GA4 code in an external javascript file (.js) [duplicate]

I have a couple of questions about the attributes async & defer for the <script> tag which to my understanding only work in HTML5 browsers.
One of my sites has two external JavaScript files that currently sit just above the </body> tag; the first is jquery sourced from google and the second is a local external script.
With respects to site load speed
Is there any advantage in adding async to the two scripts I have at the bottom of the page?
Would there be any advantage in adding the async option to the two scripts and putting them at the top of the page in the <head>?
Would this mean they download as the page loads?
I assume this would cause delays for HTML4 browsers, but would it speed up page load for HTML5 browsers?
Using <script defer src=...
Would loading the two scripts inside <head> with the attribute defer the same affect as having the scripts before </body>?
Once again I assume this would slow up HTML4 browsers.
Using <script async src=...
If I have two scripts with async enabled
Would they download at the same time?
Or one at a time with the rest of the page?
Does the order of scripts then become a problem? For example one script depends on the other so if one downloads faster, the second one might not execute correctly etc.
Finally am I best to leave things as they are until HTML5 is more commonly used?
This image explains normal script tag, async and defer
Async scripts are executed as soon as the script is loaded, so it
doesn't guarantee the order of execution (a script you included at
the end may execute before the first script file )
Defer scripts guarantees the order of execution in which they appear
in the page.
Ref this link : http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
Keep your scripts right before </body>. Async can be used with scripts located there in a few circumstances (see discussion below). Defer won't make much of a difference for scripts located there because the DOM parsing work has pretty much already been done anyway.
Here's an article that explains the difference between async and defer: http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/.
Your HTML will display quicker in older browsers if you keep the scripts at the end of the body right before </body>. So, to preserve the load speed in older browsers, you don't want to put them anywhere else.
If your second script depends upon the first script (e.g. your second script uses the jQuery loaded in the first script), then you can't make them async without additional code to control execution order, but you can make them defer because defer scripts will still be executed in order, just not until after the document has been parsed. If you have that code and you don't need the scripts to run right away, you can make them async or defer.
You could put the scripts in the <head> tag and set them to defer and the loading of the scripts will be deferred until the DOM has been parsed and that will get fast page display in new browsers that support defer, but it won't help you at all in older browsers and it isn't really any faster than just putting the scripts right before </body> which works in all browsers. So, you can see why it's just best to put them right before </body>.
Async is more useful when you really don't care when the script loads and nothing else that is user dependent depends upon that script loading. The most often cited example for using async is an analytics script like Google Analytics that you don't want anything to wait for and it's not urgent to run soon and it stands alone so nothing else depends upon it.
Usually the jQuery library is not a good candidate for async because other scripts depend upon it and you want to install event handlers so your page can start responding to user events and you may need to run some jQuery-based initialization code to establish the initial state of the page. It can be used async, but other scripts will have to be coded to not execute until jQuery is loaded.
HTML5: async, defer
In HTML5, you can tell browser when to run your JavaScript code. There are 3 possibilities:
<script src="myscript.js"></script>
<script async src="myscript.js"></script>
<script defer src="myscript.js"></script>
Without async or defer, browser will run your script immediately, before rendering the elements that's below your script tag.
With async (asynchronous), browser will continue to load the HTML page and render it while the browser load and execute the script at the same time.
With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files. This is good.)
Both async and defer scripts begin to download immediately without pausing the parser and both support an optional onload handler to address the common need to perform initialization which depends on the script.
The difference between async and defer centers around when the script is executed. Each async script executes at the first opportunity after it is finished downloading and before the window’s load event. This means it’s possible (and likely) that async scripts are not executed in the order in which they occur in the page. Whereas the defer scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document’s DOMContentLoaded event.
Source & further details: here.
Faced same kind of problem and now clearly understood how both will works.Hope this reference link will be helpful...
Async
When you add the async attribute to your script tag, the fol­low­ing will happen.
<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
Make par­al­lel requests to fetch the files.
Con­tinue pars­ing the doc­u­ment as if it was never interrupted.
Exe­cute the indi­vid­ual scripts the moment the files are downloaded.
Defer
Defer is very sim­i­lar to async with one major dif­fer­er­ence. Here’s what hap­pens when a browser encoun­ters a script with the defer attribute.
<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
Make par­al­lel requests to fetch the indi­vid­ual files.
Con­tinue pars­ing the doc­u­ment as if it was never interrupted.
Fin­ish pars­ing the doc­u­ment even if the script files have downloaded.
Exe­cute each script in the order they were encoun­tered in the document.
Reference :Difference between Async and Defer
async and defer will download the file during HTML parsing. Both will not interrupt the parser.
The script with async attribute will be executed once it is downloaded. While the script with defer attribute will be executed after completing the DOM parsing.
The scripts loaded with async doesn't guarantee any order. While the scripts loaded with defer attribute maintains the order in which they appear on the DOM.
Use <script async> when the script does not rely on anything.
when the script depends use <script defer>.
Best solution would be add the <script> at the bottom of the body. There will be no issue with blocking or rendering.
Good practice is to keep all the files in your source folder to load sorce files fast. You need to download all the script, style, icon and image related files and put these files into your project folder.
Create these folders in your project to keep different source files and then load required files into the pages from these folder.
js: to keep script related files.
css: to keep style related files.
img: to keep image/icon related files
fonts: to keep fonts related files
When to use defer and async attribute
defer attribute: First it will download the script file and then wait of html parsing. After the end of html parsing, script will execute. In other words, It will guarantee all the scripts will execute after the html parsing.
Defer attribute is useful when script is using for DOM manipulations. Means script will apply on document html.
async attribute: It will download the script file and execute without wait the end of html parsing. In other words, It will not guarantee all the scripts will execute after the html parsing.
Async attribute is useful when script is not using for DOM manipulation. Some time you need script only for server side operations or for handling cache or cookie but not for DOM manipulations. Means script is not related to the used html.
Useful link when to use defer and async:
https://stackoverflow.com/a/68929270/7186739
I think Jake Archibald presented us some insights back in 2013 that might add even more positiveness to the topic:
https://www.html5rocks.com/en/tutorials/speed/script-loading/
The holy grail is having a set of scripts download immediately without blocking rendering and execute as soon as possible in the order they were added. Unfortunately HTML hates you and won’t let you do that.
(...)
The answer is actually in the HTML5 spec, although it’s hidden away at the bottom of the script-loading section.
"The async IDL attribute controls whether the element will execute asynchronously or not. If the element's "force-async" flag is set, then, on getting, the async IDL attribute must return true, and on setting, the "force-async" flag must first be unset…".
(...)
Scripts that are dynamically created and added to the document are async by default, they don’t block rendering and execute as soon as they download, meaning they could come out in the wrong order. However, we can explicitly mark them as not async:
[
'//other-domain.com/1.js',
'2.js'
].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
This gives our scripts a mix of behaviour that can’t be achieved with plain HTML. By being explicitly not async, scripts are added to an execution queue, the same queue they’re added to in our first plain-HTML example. However, by being dynamically created, they’re executed outside of document parsing, so rendering isn’t blocked while they’re downloaded (don’t confuse not-async script loading with sync XHR, which is never a good thing).
The script above should be included inline in the head of pages, queueing script downloads as soon as possible without disrupting progressive rendering, and executes as soon as possible in the order you specified. “2.js” is free to download before “1.js”, but it won’t be executed until “1.js” has either successfully downloaded and executed, or fails to do either. Hurrah! async-download but ordered-execution!
Still, this might not be the fastest way to load scripts:
(...) With the example above the browser has to parse and execute script to discover which scripts to download. This hides your scripts from preload scanners. Browsers use these scanners to discover resources on pages you’re likely to visit next, or discover page resources while the parser is blocked by another resource.
We can add discoverability back in by putting this in the head of the document:
<link rel="subresource" href="//other-domain.com/1.js">
<link rel="subresource" href="2.js">
This tells the browser the page needs 1.js and 2.js. link[rel=subresource] is similar to link[rel=prefetch], but with different semantics. Unfortunately it’s currently only supported in Chrome, and you have to declare which scripts to load twice, once via link elements, and again in your script.
Correction: I originally stated these were picked up by the preload scanner, they're not, they're picked up by the regular parser. However, preload scanner could pick these up, it just doesn't yet, whereas scripts included by executable code can never be preloaded. Thanks to Yoav Weiss who corrected me in the comments.
Rendering engine goes several steps till it paints anything on the screen.
it looks like this:
Converting HTML bytes to characters depending on encoding we set to the document;
Tokens are created according to characters. Tokens mean analyze characters and specify opening tangs and nested tags;
From tokens separated nodes are created. they are objects and according to information delivered from tokenization process, engine creates objects which includes all necessary information about each node;
after that DOM is created. DOM is tree data structure and represents whole hierarchy and information about relationship and specification of tags;
The same process goes to CSS. for CSS rendering engine creates different/separated data structure for CSS but it's called CSSOM (CSS Object Model)
Browser works only with Object models so it needs to know all information about DOM and CSSDOM.
The next step is combining somehow DOM and CSSOM. because without CSSOM browser do not know how to style each element during rendering process.
All information above means that, anything you provide in your html (javascript, css ) browser will pause DOM construction process. If you are familiar with event loop, there is simple rule how event loop executes tasks:
Execute macro tasks;
execute micro tasks;
Rendering;
So when you provide Javascript file, browser do not know what JS code is going to do and stops all DOM construction process and Javascript interptreter starts parsing and executing Javascript code.
Even you provide Javascript in the end of body tag, Browser will proceed all above steps to HTML and CSS but except rendering. it will find out Script tag and will stop until JS is done.
But HTML provided two additional options for script tag: async and defer.
Async - means execute code when it is downloaded and do not block DOM construction during downloading process.
Defer - means execute code after it's downloaded and browser finished DOM construction and rendering process.
It seems the behavior of defer and async is browser dependent, at least on the execution phase. NOTE, defer only applies to external scripts. I'm assuming async follows same pattern.
In IE 11 and below, the order seems to be like this:
async (could partially execute while page loading)
none (could execute while page loading)
defer (executes after page loaded, all defer in order of placement in file)
In Edge, Webkit, etc, the async attribute seems to be either ignored or placed at the end:
data-pagespeed-no-defer (executes before any other scripts, while page is loading)
none (could execute while page is loading)
defer (waits until DOM loaded, all defer in order of placement in file)
async (seems to wait until DOM loaded)
In newer browsers, the data-pagespeed-no-defer attribute runs before any other external scripts. This is for scripts that don't depend on the DOM.
NOTE: Use defer when you need an explicit order of execution of your external scripts. This tells the browser to execute all deferred scripts in order of placement in the file.
ASIDE: The size of the external javascripts did matter when loading...but had no effect on the order of execution.
If you're worried about the performance of your scripts, you may want to consider minification or simply loading them dynamically with an XMLHttpRequest.
Default - By default, as soon as the browser sees a script tag it downloads the file and then executes the script file. The script files are executed in the order of their occurrence.
async - The browser will download the script file and continue parsing HTML parallelly until the file is downloaded. The file is executed as soon as it is downloaded.
defer - The browser will download the script and do HTML parsing at the same time. After parsing is done, the script files are executed in the order of their occurrence.
Note:
In defer, the js files are executed in the order of their occurrence in the HTML file while in the case of the async attribute the script files are executed in the order of download time.
Async is suitable if your script doesn’t contains DOM manipulation and other scripts doesn’t depend upon on this.
Eg: bootstrap cdn,jquery
Defer is suitable if your script contains DOM manipulation and other scripts depend upon on this.
Eg: <script src=”createfirst.js”> //let this will create element <script src=”showfirst.js”> //after createfirst create element it will show that.
Thus make it:
Eg: <script defer src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will
This will execute scripts in order.
But if i made:
Eg: <script async src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will
Then, this code might result unexpected results.
Coz: if html parser access createfirst script.It won’t stop DOM creation and starts downloading code from src .Once src got resolved/code got downloaded, it will execute immediately parallel with DOM.
What if showfirst.js execute first than createfirst.js.This might be possible if createfirst takes long time (Assume after DOM parsing finished).Then, showfirst will execute immediately.

Difference between script tag with and without "async"? [duplicate]

I have a couple of questions about the attributes async & defer for the <script> tag which to my understanding only work in HTML5 browsers.
One of my sites has two external JavaScript files that currently sit just above the </body> tag; the first is jquery sourced from google and the second is a local external script.
With respects to site load speed
Is there any advantage in adding async to the two scripts I have at the bottom of the page?
Would there be any advantage in adding the async option to the two scripts and putting them at the top of the page in the <head>?
Would this mean they download as the page loads?
I assume this would cause delays for HTML4 browsers, but would it speed up page load for HTML5 browsers?
Using <script defer src=...
Would loading the two scripts inside <head> with the attribute defer the same affect as having the scripts before </body>?
Once again I assume this would slow up HTML4 browsers.
Using <script async src=...
If I have two scripts with async enabled
Would they download at the same time?
Or one at a time with the rest of the page?
Does the order of scripts then become a problem? For example one script depends on the other so if one downloads faster, the second one might not execute correctly etc.
Finally am I best to leave things as they are until HTML5 is more commonly used?
This image explains normal script tag, async and defer
Async scripts are executed as soon as the script is loaded, so it
doesn't guarantee the order of execution (a script you included at
the end may execute before the first script file )
Defer scripts guarantees the order of execution in which they appear
in the page.
Ref this link : http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
Keep your scripts right before </body>. Async can be used with scripts located there in a few circumstances (see discussion below). Defer won't make much of a difference for scripts located there because the DOM parsing work has pretty much already been done anyway.
Here's an article that explains the difference between async and defer: http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/.
Your HTML will display quicker in older browsers if you keep the scripts at the end of the body right before </body>. So, to preserve the load speed in older browsers, you don't want to put them anywhere else.
If your second script depends upon the first script (e.g. your second script uses the jQuery loaded in the first script), then you can't make them async without additional code to control execution order, but you can make them defer because defer scripts will still be executed in order, just not until after the document has been parsed. If you have that code and you don't need the scripts to run right away, you can make them async or defer.
You could put the scripts in the <head> tag and set them to defer and the loading of the scripts will be deferred until the DOM has been parsed and that will get fast page display in new browsers that support defer, but it won't help you at all in older browsers and it isn't really any faster than just putting the scripts right before </body> which works in all browsers. So, you can see why it's just best to put them right before </body>.
Async is more useful when you really don't care when the script loads and nothing else that is user dependent depends upon that script loading. The most often cited example for using async is an analytics script like Google Analytics that you don't want anything to wait for and it's not urgent to run soon and it stands alone so nothing else depends upon it.
Usually the jQuery library is not a good candidate for async because other scripts depend upon it and you want to install event handlers so your page can start responding to user events and you may need to run some jQuery-based initialization code to establish the initial state of the page. It can be used async, but other scripts will have to be coded to not execute until jQuery is loaded.
HTML5: async, defer
In HTML5, you can tell browser when to run your JavaScript code. There are 3 possibilities:
<script src="myscript.js"></script>
<script async src="myscript.js"></script>
<script defer src="myscript.js"></script>
Without async or defer, browser will run your script immediately, before rendering the elements that's below your script tag.
With async (asynchronous), browser will continue to load the HTML page and render it while the browser load and execute the script at the same time.
With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files. This is good.)
Both async and defer scripts begin to download immediately without pausing the parser and both support an optional onload handler to address the common need to perform initialization which depends on the script.
The difference between async and defer centers around when the script is executed. Each async script executes at the first opportunity after it is finished downloading and before the window’s load event. This means it’s possible (and likely) that async scripts are not executed in the order in which they occur in the page. Whereas the defer scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document’s DOMContentLoaded event.
Source & further details: here.
Faced same kind of problem and now clearly understood how both will works.Hope this reference link will be helpful...
Async
When you add the async attribute to your script tag, the fol­low­ing will happen.
<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
Make par­al­lel requests to fetch the files.
Con­tinue pars­ing the doc­u­ment as if it was never interrupted.
Exe­cute the indi­vid­ual scripts the moment the files are downloaded.
Defer
Defer is very sim­i­lar to async with one major dif­fer­er­ence. Here’s what hap­pens when a browser encoun­ters a script with the defer attribute.
<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
Make par­al­lel requests to fetch the indi­vid­ual files.
Con­tinue pars­ing the doc­u­ment as if it was never interrupted.
Fin­ish pars­ing the doc­u­ment even if the script files have downloaded.
Exe­cute each script in the order they were encoun­tered in the document.
Reference :Difference between Async and Defer
async and defer will download the file during HTML parsing. Both will not interrupt the parser.
The script with async attribute will be executed once it is downloaded. While the script with defer attribute will be executed after completing the DOM parsing.
The scripts loaded with async doesn't guarantee any order. While the scripts loaded with defer attribute maintains the order in which they appear on the DOM.
Use <script async> when the script does not rely on anything.
when the script depends use <script defer>.
Best solution would be add the <script> at the bottom of the body. There will be no issue with blocking or rendering.
Good practice is to keep all the files in your source folder to load sorce files fast. You need to download all the script, style, icon and image related files and put these files into your project folder.
Create these folders in your project to keep different source files and then load required files into the pages from these folder.
js: to keep script related files.
css: to keep style related files.
img: to keep image/icon related files
fonts: to keep fonts related files
When to use defer and async attribute
defer attribute: First it will download the script file and then wait of html parsing. After the end of html parsing, script will execute. In other words, It will guarantee all the scripts will execute after the html parsing.
Defer attribute is useful when script is using for DOM manipulations. Means script will apply on document html.
async attribute: It will download the script file and execute without wait the end of html parsing. In other words, It will not guarantee all the scripts will execute after the html parsing.
Async attribute is useful when script is not using for DOM manipulation. Some time you need script only for server side operations or for handling cache or cookie but not for DOM manipulations. Means script is not related to the used html.
Useful link when to use defer and async:
https://stackoverflow.com/a/68929270/7186739
I think Jake Archibald presented us some insights back in 2013 that might add even more positiveness to the topic:
https://www.html5rocks.com/en/tutorials/speed/script-loading/
The holy grail is having a set of scripts download immediately without blocking rendering and execute as soon as possible in the order they were added. Unfortunately HTML hates you and won’t let you do that.
(...)
The answer is actually in the HTML5 spec, although it’s hidden away at the bottom of the script-loading section.
"The async IDL attribute controls whether the element will execute asynchronously or not. If the element's "force-async" flag is set, then, on getting, the async IDL attribute must return true, and on setting, the "force-async" flag must first be unset…".
(...)
Scripts that are dynamically created and added to the document are async by default, they don’t block rendering and execute as soon as they download, meaning they could come out in the wrong order. However, we can explicitly mark them as not async:
[
'//other-domain.com/1.js',
'2.js'
].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
This gives our scripts a mix of behaviour that can’t be achieved with plain HTML. By being explicitly not async, scripts are added to an execution queue, the same queue they’re added to in our first plain-HTML example. However, by being dynamically created, they’re executed outside of document parsing, so rendering isn’t blocked while they’re downloaded (don’t confuse not-async script loading with sync XHR, which is never a good thing).
The script above should be included inline in the head of pages, queueing script downloads as soon as possible without disrupting progressive rendering, and executes as soon as possible in the order you specified. “2.js” is free to download before “1.js”, but it won’t be executed until “1.js” has either successfully downloaded and executed, or fails to do either. Hurrah! async-download but ordered-execution!
Still, this might not be the fastest way to load scripts:
(...) With the example above the browser has to parse and execute script to discover which scripts to download. This hides your scripts from preload scanners. Browsers use these scanners to discover resources on pages you’re likely to visit next, or discover page resources while the parser is blocked by another resource.
We can add discoverability back in by putting this in the head of the document:
<link rel="subresource" href="//other-domain.com/1.js">
<link rel="subresource" href="2.js">
This tells the browser the page needs 1.js and 2.js. link[rel=subresource] is similar to link[rel=prefetch], but with different semantics. Unfortunately it’s currently only supported in Chrome, and you have to declare which scripts to load twice, once via link elements, and again in your script.
Correction: I originally stated these were picked up by the preload scanner, they're not, they're picked up by the regular parser. However, preload scanner could pick these up, it just doesn't yet, whereas scripts included by executable code can never be preloaded. Thanks to Yoav Weiss who corrected me in the comments.
Rendering engine goes several steps till it paints anything on the screen.
it looks like this:
Converting HTML bytes to characters depending on encoding we set to the document;
Tokens are created according to characters. Tokens mean analyze characters and specify opening tangs and nested tags;
From tokens separated nodes are created. they are objects and according to information delivered from tokenization process, engine creates objects which includes all necessary information about each node;
after that DOM is created. DOM is tree data structure and represents whole hierarchy and information about relationship and specification of tags;
The same process goes to CSS. for CSS rendering engine creates different/separated data structure for CSS but it's called CSSOM (CSS Object Model)
Browser works only with Object models so it needs to know all information about DOM and CSSDOM.
The next step is combining somehow DOM and CSSOM. because without CSSOM browser do not know how to style each element during rendering process.
All information above means that, anything you provide in your html (javascript, css ) browser will pause DOM construction process. If you are familiar with event loop, there is simple rule how event loop executes tasks:
Execute macro tasks;
execute micro tasks;
Rendering;
So when you provide Javascript file, browser do not know what JS code is going to do and stops all DOM construction process and Javascript interptreter starts parsing and executing Javascript code.
Even you provide Javascript in the end of body tag, Browser will proceed all above steps to HTML and CSS but except rendering. it will find out Script tag and will stop until JS is done.
But HTML provided two additional options for script tag: async and defer.
Async - means execute code when it is downloaded and do not block DOM construction during downloading process.
Defer - means execute code after it's downloaded and browser finished DOM construction and rendering process.
It seems the behavior of defer and async is browser dependent, at least on the execution phase. NOTE, defer only applies to external scripts. I'm assuming async follows same pattern.
In IE 11 and below, the order seems to be like this:
async (could partially execute while page loading)
none (could execute while page loading)
defer (executes after page loaded, all defer in order of placement in file)
In Edge, Webkit, etc, the async attribute seems to be either ignored or placed at the end:
data-pagespeed-no-defer (executes before any other scripts, while page is loading)
none (could execute while page is loading)
defer (waits until DOM loaded, all defer in order of placement in file)
async (seems to wait until DOM loaded)
In newer browsers, the data-pagespeed-no-defer attribute runs before any other external scripts. This is for scripts that don't depend on the DOM.
NOTE: Use defer when you need an explicit order of execution of your external scripts. This tells the browser to execute all deferred scripts in order of placement in the file.
ASIDE: The size of the external javascripts did matter when loading...but had no effect on the order of execution.
If you're worried about the performance of your scripts, you may want to consider minification or simply loading them dynamically with an XMLHttpRequest.
Default - By default, as soon as the browser sees a script tag it downloads the file and then executes the script file. The script files are executed in the order of their occurrence.
async - The browser will download the script file and continue parsing HTML parallelly until the file is downloaded. The file is executed as soon as it is downloaded.
defer - The browser will download the script and do HTML parsing at the same time. After parsing is done, the script files are executed in the order of their occurrence.
Note:
In defer, the js files are executed in the order of their occurrence in the HTML file while in the case of the async attribute the script files are executed in the order of download time.
Async is suitable if your script doesn’t contains DOM manipulation and other scripts doesn’t depend upon on this.
Eg: bootstrap cdn,jquery
Defer is suitable if your script contains DOM manipulation and other scripts depend upon on this.
Eg: <script src=”createfirst.js”> //let this will create element <script src=”showfirst.js”> //after createfirst create element it will show that.
Thus make it:
Eg: <script defer src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will
This will execute scripts in order.
But if i made:
Eg: <script async src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will
Then, this code might result unexpected results.
Coz: if html parser access createfirst script.It won’t stop DOM creation and starts downloading code from src .Once src got resolved/code got downloaded, it will execute immediately parallel with DOM.
What if showfirst.js execute first than createfirst.js.This might be possible if createfirst takes long time (Assume after DOM parsing finished).Then, showfirst will execute immediately.

HTML DOM appendChild script async [duplicate]

I have a couple of questions about the attributes async & defer for the <script> tag which to my understanding only work in HTML5 browsers.
One of my sites has two external JavaScript files that currently sit just above the </body> tag; the first is jquery sourced from google and the second is a local external script.
With respects to site load speed
Is there any advantage in adding async to the two scripts I have at the bottom of the page?
Would there be any advantage in adding the async option to the two scripts and putting them at the top of the page in the <head>?
Would this mean they download as the page loads?
I assume this would cause delays for HTML4 browsers, but would it speed up page load for HTML5 browsers?
Using <script defer src=...
Would loading the two scripts inside <head> with the attribute defer the same affect as having the scripts before </body>?
Once again I assume this would slow up HTML4 browsers.
Using <script async src=...
If I have two scripts with async enabled
Would they download at the same time?
Or one at a time with the rest of the page?
Does the order of scripts then become a problem? For example one script depends on the other so if one downloads faster, the second one might not execute correctly etc.
Finally am I best to leave things as they are until HTML5 is more commonly used?
This image explains normal script tag, async and defer
Async scripts are executed as soon as the script is loaded, so it
doesn't guarantee the order of execution (a script you included at
the end may execute before the first script file )
Defer scripts guarantees the order of execution in which they appear
in the page.
Ref this link : http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
Keep your scripts right before </body>. Async can be used with scripts located there in a few circumstances (see discussion below). Defer won't make much of a difference for scripts located there because the DOM parsing work has pretty much already been done anyway.
Here's an article that explains the difference between async and defer: http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/.
Your HTML will display quicker in older browsers if you keep the scripts at the end of the body right before </body>. So, to preserve the load speed in older browsers, you don't want to put them anywhere else.
If your second script depends upon the first script (e.g. your second script uses the jQuery loaded in the first script), then you can't make them async without additional code to control execution order, but you can make them defer because defer scripts will still be executed in order, just not until after the document has been parsed. If you have that code and you don't need the scripts to run right away, you can make them async or defer.
You could put the scripts in the <head> tag and set them to defer and the loading of the scripts will be deferred until the DOM has been parsed and that will get fast page display in new browsers that support defer, but it won't help you at all in older browsers and it isn't really any faster than just putting the scripts right before </body> which works in all browsers. So, you can see why it's just best to put them right before </body>.
Async is more useful when you really don't care when the script loads and nothing else that is user dependent depends upon that script loading. The most often cited example for using async is an analytics script like Google Analytics that you don't want anything to wait for and it's not urgent to run soon and it stands alone so nothing else depends upon it.
Usually the jQuery library is not a good candidate for async because other scripts depend upon it and you want to install event handlers so your page can start responding to user events and you may need to run some jQuery-based initialization code to establish the initial state of the page. It can be used async, but other scripts will have to be coded to not execute until jQuery is loaded.
HTML5: async, defer
In HTML5, you can tell browser when to run your JavaScript code. There are 3 possibilities:
<script src="myscript.js"></script>
<script async src="myscript.js"></script>
<script defer src="myscript.js"></script>
Without async or defer, browser will run your script immediately, before rendering the elements that's below your script tag.
With async (asynchronous), browser will continue to load the HTML page and render it while the browser load and execute the script at the same time.
With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files. This is good.)
Both async and defer scripts begin to download immediately without pausing the parser and both support an optional onload handler to address the common need to perform initialization which depends on the script.
The difference between async and defer centers around when the script is executed. Each async script executes at the first opportunity after it is finished downloading and before the window’s load event. This means it’s possible (and likely) that async scripts are not executed in the order in which they occur in the page. Whereas the defer scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document’s DOMContentLoaded event.
Source & further details: here.
Faced same kind of problem and now clearly understood how both will works.Hope this reference link will be helpful...
Async
When you add the async attribute to your script tag, the fol­low­ing will happen.
<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
Make par­al­lel requests to fetch the files.
Con­tinue pars­ing the doc­u­ment as if it was never interrupted.
Exe­cute the indi­vid­ual scripts the moment the files are downloaded.
Defer
Defer is very sim­i­lar to async with one major dif­fer­er­ence. Here’s what hap­pens when a browser encoun­ters a script with the defer attribute.
<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
Make par­al­lel requests to fetch the indi­vid­ual files.
Con­tinue pars­ing the doc­u­ment as if it was never interrupted.
Fin­ish pars­ing the doc­u­ment even if the script files have downloaded.
Exe­cute each script in the order they were encoun­tered in the document.
Reference :Difference between Async and Defer
async and defer will download the file during HTML parsing. Both will not interrupt the parser.
The script with async attribute will be executed once it is downloaded. While the script with defer attribute will be executed after completing the DOM parsing.
The scripts loaded with async doesn't guarantee any order. While the scripts loaded with defer attribute maintains the order in which they appear on the DOM.
Use <script async> when the script does not rely on anything.
when the script depends use <script defer>.
Best solution would be add the <script> at the bottom of the body. There will be no issue with blocking or rendering.
Good practice is to keep all the files in your source folder to load source files fast. You need to download all the script, style, icon, and image-related files and put these files into your project folder.
Create these folders in your project to keep different source files and then load the required files into the pages from this folder.
JS: to keep script-related files.
CSS: to keep style-related files.
images: to keep image/icon-related files
fonts: to keep font-related files
When to use defer and async attributes on the <script> tag
defer attribute: First the defer attribute will download the script file and then wait for HTML parsing. After the end of the HTML parsing, the script will execute. In other words, it will guarantee all the scripts will execute after the HTML parsing.
The defer attribute is useful when the script is used for DOM manipulations.
async attribute: The async attribute will download the script file and execute without waiting for the end of HTML parsing. In other words, it does not guarantee that all the scripts will execute after the HTML parsing.
The async attribute is useful when the script is not used for DOM manipulation. Sometimes you need a script only for server-side operations or for handling cache or cookies, but not for DOM manipulations.
Useful link when to use defer and async:
https://stackoverflow.com/a/68929270/7186739
I think Jake Archibald presented us some insights back in 2013 that might add even more positiveness to the topic:
https://www.html5rocks.com/en/tutorials/speed/script-loading/
The holy grail is having a set of scripts download immediately without blocking rendering and execute as soon as possible in the order they were added. Unfortunately HTML hates you and won’t let you do that.
(...)
The answer is actually in the HTML5 spec, although it’s hidden away at the bottom of the script-loading section.
"The async IDL attribute controls whether the element will execute asynchronously or not. If the element's "force-async" flag is set, then, on getting, the async IDL attribute must return true, and on setting, the "force-async" flag must first be unset…".
(...)
Scripts that are dynamically created and added to the document are async by default, they don’t block rendering and execute as soon as they download, meaning they could come out in the wrong order. However, we can explicitly mark them as not async:
[
'//other-domain.com/1.js',
'2.js'
].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
This gives our scripts a mix of behaviour that can’t be achieved with plain HTML. By being explicitly not async, scripts are added to an execution queue, the same queue they’re added to in our first plain-HTML example. However, by being dynamically created, they’re executed outside of document parsing, so rendering isn’t blocked while they’re downloaded (don’t confuse not-async script loading with sync XHR, which is never a good thing).
The script above should be included inline in the head of pages, queueing script downloads as soon as possible without disrupting progressive rendering, and executes as soon as possible in the order you specified. “2.js” is free to download before “1.js”, but it won’t be executed until “1.js” has either successfully downloaded and executed, or fails to do either. Hurrah! async-download but ordered-execution!
Still, this might not be the fastest way to load scripts:
(...) With the example above the browser has to parse and execute script to discover which scripts to download. This hides your scripts from preload scanners. Browsers use these scanners to discover resources on pages you’re likely to visit next, or discover page resources while the parser is blocked by another resource.
We can add discoverability back in by putting this in the head of the document:
<link rel="subresource" href="//other-domain.com/1.js">
<link rel="subresource" href="2.js">
This tells the browser the page needs 1.js and 2.js. link[rel=subresource] is similar to link[rel=prefetch], but with different semantics. Unfortunately it’s currently only supported in Chrome, and you have to declare which scripts to load twice, once via link elements, and again in your script.
Correction: I originally stated these were picked up by the preload scanner, they're not, they're picked up by the regular parser. However, preload scanner could pick these up, it just doesn't yet, whereas scripts included by executable code can never be preloaded. Thanks to Yoav Weiss who corrected me in the comments.
Rendering engine goes several steps till it paints anything on the screen.
it looks like this:
Converting HTML bytes to characters depending on encoding we set to the document;
Tokens are created according to characters. Tokens mean analyze characters and specify opening tangs and nested tags;
From tokens separated nodes are created. they are objects and according to information delivered from tokenization process, engine creates objects which includes all necessary information about each node;
after that DOM is created. DOM is tree data structure and represents whole hierarchy and information about relationship and specification of tags;
The same process goes to CSS. for CSS rendering engine creates different/separated data structure for CSS but it's called CSSOM (CSS Object Model)
Browser works only with Object models so it needs to know all information about DOM and CSSDOM.
The next step is combining somehow DOM and CSSOM. because without CSSOM browser do not know how to style each element during rendering process.
All information above means that, anything you provide in your html (javascript, css ) browser will pause DOM construction process. If you are familiar with event loop, there is simple rule how event loop executes tasks:
Execute macro tasks;
execute micro tasks;
Rendering;
So when you provide Javascript file, browser do not know what JS code is going to do and stops all DOM construction process and Javascript interptreter starts parsing and executing Javascript code.
Even you provide Javascript in the end of body tag, Browser will proceed all above steps to HTML and CSS but except rendering. it will find out Script tag and will stop until JS is done.
But HTML provided two additional options for script tag: async and defer.
Async - means execute code when it is downloaded and do not block DOM construction during downloading process.
Defer - means execute code after it's downloaded and browser finished DOM construction and rendering process.
It seems the behavior of defer and async is browser dependent, at least on the execution phase. NOTE, defer only applies to external scripts. I'm assuming async follows same pattern.
In IE 11 and below, the order seems to be like this:
async (could partially execute while page loading)
none (could execute while page loading)
defer (executes after page loaded, all defer in order of placement in file)
In Edge, Webkit, etc, the async attribute seems to be either ignored or placed at the end:
data-pagespeed-no-defer (executes before any other scripts, while page is loading)
none (could execute while page is loading)
defer (waits until DOM loaded, all defer in order of placement in file)
async (seems to wait until DOM loaded)
In newer browsers, the data-pagespeed-no-defer attribute runs before any other external scripts. This is for scripts that don't depend on the DOM.
NOTE: Use defer when you need an explicit order of execution of your external scripts. This tells the browser to execute all deferred scripts in order of placement in the file.
ASIDE: The size of the external javascripts did matter when loading...but had no effect on the order of execution.
If you're worried about the performance of your scripts, you may want to consider minification or simply loading them dynamically with an XMLHttpRequest.
Default - By default, as soon as the browser sees a script tag it downloads the file and then executes the script file. The script files are executed in the order of their occurrence.
async - The browser will download the script file and continue parsing HTML parallelly until the file is downloaded. The file is executed as soon as it is downloaded.
defer - The browser will download the script and do HTML parsing at the same time. After parsing is done, the script files are executed in the order of their occurrence.
Note:
In defer, the js files are executed in the order of their occurrence in the HTML file while in the case of the async attribute the script files are executed in the order of download time.
Async is suitable if your script doesn’t contains DOM manipulation and other scripts doesn’t depend upon on this.
Eg: bootstrap cdn,jquery
Defer is suitable if your script contains DOM manipulation and other scripts depend upon on this.
Eg: <script src=”createfirst.js”> //let this will create element <script src=”showfirst.js”> //after createfirst create element it will show that.
Thus make it:
Eg: <script defer src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will
This will execute scripts in order.
But if i made:
Eg: <script async src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will
Then, this code might result unexpected results.
Coz: if html parser access createfirst script.It won’t stop DOM creation and starts downloading code from src .Once src got resolved/code got downloaded, it will execute immediately parallel with DOM.
What if showfirst.js execute first than createfirst.js.This might be possible if createfirst takes long time (Assume after DOM parsing finished).Then, showfirst will execute immediately.

Can you use both the async and defer attributes on a HTML tag?

I would like to load in the following JavaScript code using both defer and async:
<script defer async src="/js/somescript.js"></script>
Since defer is supported by Internet Explorer 5.5+, as you can see at CanIUse.com, I would like to gracefully fallback to using defer if async is not available. Async I think is better to use when it is available but its not supported until Internet Explorer 10.
My question is therefore is the above code valid HTML? If not, is it possible to create this situation using JavaScript of gracefully falling back to using defer on a script when async is not available?
From the specification: https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async
The defer attribute may be specified even if the async attribute is specified, to cause legacy Web browsers that only support defer (and not async) to fall back to the defer behavior instead of the synchronous blocking behavior that is the default.
(Check the reference link below to see a visual representation of the differences between normal scripts and scripts with defer and async)
References:
async vs defer attributes
Efficiently load JavaScript with defer and async
The question is, what would you expect it to do?
If both async and defer are present I would expect the script to be deferred and only executed after DOMContentLoaded when the browser is idle, but if I'm reading the specification right it looks like defer is ignored if async is set and the script is loaded asynchronously, so will execute as soon as it's available, which may well be before DOMContentLoaded and may block other resources.
There are three possible modes that can be selected using these attributes. If the async attribute is present, then the script will be executed asynchronously, as soon as it is available. If the async attribute is not present but the defer attribute is present, then the script is executed when the page has finished parsing. If neither attribute is present, then the script is fetched and executed immediately, before the user agent continues parsing the page.
https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async
Unfortunately defer is ignored when async specified, and async always have higher priority.
And personally I think that it's very bad that defer is ignored. Let's imagine situation when we would like to have some JS initialized ASAP, even before loading of the page content. But we want this script initialized BEFORE the rest of scripts which requires it. It should be first in defer queue. But, unfortunately, this will not work:
<!-- we want "jQuery" ASAP and still in "defer" queue. But defer is ignored. -->
<script src="jquery.min.js" async defer></script>
<!-- this doesn't blocks the content and can wait the full page load, but requires "jQuery" -->
<script src="some_jquery_plugin.min.js" defer></script>
In this sample the "some_jquery_plugin.min.js" can be loaded and executed before the load of jQuery, and will fail. :(
So there is 2 ways to solve the problem: either use only defer directive, or merge all depending javascript files into single JS.
Yes, its valid HTML and it will work like expected.
Any W3C compliant browser will recognize the async attribute and treat the script properly, whereas legacy IE versions will recognize the defer attribute.
Since both attributes are boolean you don't have to assign any value.
Yes, you can use both attributes but you need to use defer or async, not both. For more see the comparison and use one based on your need.
defer attribute: First it will download the script file and then wait of html parsing. After the end of html parsing, script will execute. In other words, It will guarantee all the scripts will execute after the html parsing.
Defer attribute is useful when script is using for DOM manipulations. Means script will apply on document html.
async attribute: It will download the script file and execute without wait the end of html parsing. In other words, It will not guarantee all the scripts will execute after the html parsing.
Async attribute is useful when script is not using for DOM manipulation. Some time you need script only for server side operations or for handling cache or cookie but not for DOM manipulations. Means script is not related to the used html.
Actually, there is a misconception in most comments here. People don´t seem to know that DEFER also loads the code in parallel, just like ASYNC. But it waits to execute after DOM loads (but before DOMContentLoaded executes), while ASYNC runs it immediately after loading, before DOM loads. Since BOTH ASYNC and DEFER load code in parallel, there would be no need to use both together (but to deal with legacy, maybe).

async="async" attribute of a <script> tag in html, What does it mean?

async="async" attribute of a <script> tag in HTML, What does it mean?
<script async="async" src="...."></script>
Can be see used here for example
If the async attribute is set on an external script (one with src=), browsers that support it will download that script in the background without blocking the rest of the content on the page. The script will execute whenever it is finished downloading.
http://dev.w3.org/html5/spec/Overview.html#attr-script-async
As I mentioned in a comment, setting async=true, async=false or async=anything all mean the same thing. They enable the async behavior. The only way to make a script non-async is to completely omit the attribute.
http://dev.w3.org/html5/spec/Overview.html#boolean-attributes
In XHTML it is needed to consequently note attributes as attributes and their values whereas HTML does not. I like the conformity of that principle so I always use it in the form of:
async="async"
This way I can serve my documents as application/xhtml+xml.
If this is not of any interest for you because you are of the opinion that serving your document as text/html is good enough, then you can always use:
async
It simply means
Download the External Script asyncronously ( or in parallel ) without blocking the html parsing.
The Script once downloaded will be Executed Immediately blocking the html parsing.
Here's a nice illustration.
Note : This attribute works only for the external scripts ( the one's with the src attribute ) and not inline scripts.
The HTML WHATWG specification contains the following explanation:
For classic scripts, if the async attribute is present, then the
classic script will be fetched in parallel to parsing and evaluated as
soon as it is available (potentially before parsing completes). If the
async attribute is not present but the defer attribute is present,
then the classic script will be fetched in parallel and evaluated when
the page has finished parsing. If neither attribute is present, then
the script is fetched and evaluated immediately, blocking parsing
until these are both complete.
For module scripts, if the async attribute is present, then the module
script and all its dependencies will be fetched in parallel to
parsing, and the module script will be evaluated as soon as it is
available (potentially before parsing completes). Otherwise, the
module script and its dependencies will be fetched in parallel to
parsing and evaluated when the page has finished parsing. (The defer
attribute has no effect on module scripts.)
This is all summarized in the following schematic diagram:
The exact processing details for these attributes are, for mostly historical reasons, somewhat non-trivial, involving a number of aspects of HTML. The implementation requirements are therefore by necessity scattered throughout the specification. The algorithms [described in the HTML specification] describe the core of this processing, but these algorithms reference and are referenced by the parsing rules for script start and end tags in HTML, in foreign content, and in XML, the rules for the document.write() method, the handling of scripting, etc.
The defer attribute may be specified even if the async attribute is specified, to cause legacy Web browsers that only support defer (and not async) to fall back to the defer behavior instead of the blocking behavior that is the default.
Seems it doesn't need to be async=async either, but just async
From google:
A second technique is to use the attribute where
appropriate, which prevents parsing from blocking the initial page
load by deferring it until the browser's UI thread is not busy doing
something else.
https://developers.google.com/speed/docs/best-practices/mobile#DeferParsingJS
Just async in enough.
You may try both and then measure the difference in page speed. Like crictime uses single substance for that.

Categories

Resources