Why doesn't CSS block download of page while scripts do? - javascript

I hear a lot that you should put your scripts at the end of your markup because the page needs to download the script and then execute it before moving forward to render/execute the rest of the page. How is this different than stylesheets? How come the page can keep going with stylesheets and isn't slowed down by them. Don't stylesheets also need to be downloaded and executed before the page continues to be executed by the browser?

CSS and JavaScript are two different contexts.
CSS is just a set of rules while JavaScript:
Needs to be executed in a thread meaning it's going to be busy doing its own stuff not to mention that if you're going to use any I/O it will take even longer, so just put it at the footer so all your CSS and HTML load correctly and fast, then you can load your JavaScript script.
You could also do an async script but it depends on the functionality of this script as well.

Request at <link rel="stylesheet" href="/path/to/style.css"> is blocking.

Styles are loaded asynchronously.
In fact, you do not need to put script at the end of page. You can put script in the header. But at the same time set the attributes async or defer.
<script async src="/yourpath/file.js"></script>
// or
<script defer src="/yourpath/file.js"></script>

Related

Is adding defer to a script tag at the end of a closing body tag redundant?

for example:
<body>
...all content is above the script...
<script src="https://foo/bar.js" defer></script>
</body>
Does it matter if we remove the defer from the script tag? By putting the script at the end of the body tag is already delaying the execution of the script so the above code should be the same as the following snippet right?
<body>
...all content is above the script...
<script src="https://foo/bar.js"></script>
</body>
According to Ben
The current best practice? Use deferred scripts in order in the head, unless you need to support older browsers (IE < 10, Opera Mini,
etc.) - 97.45% browser usage (ref)
Why? With defer, parsing finishes just like when we put the script at the end of the body tag, but overall the script execution finishes
well before, because the script has been downloaded in parallel with
the HTML parsing. This scenario will trigger the faster domInteractive
event that is used for page loading speed. With async, the order in
which your script will execute varies based on how fast the script is
fetched, so order can be compromised. Futhermore, async scripts are
executed inline and pause the parsing of the HTML.
Also from Mhmdrz_A
Browser will parse the document from top to bottom, hence putting the
scripts after all the main content will make the parser to reach that
later in time; which make the browser to download the script
later in time; The delay caused by putting the defer in the bottom is
absolutely non-sense, since the browser won't execute them (s) before (or during) HTML parser;
Thus it's better to let the browser load ( download ) them () as soon as possible, an have them available to execute as soon
as the all the main tasks are done.
Does it matter if we remove the defer from the script tag? By putting
the script at the end of the body tag is already delaying the
execution of the script so the above code should be the same as the
following snippet right?
Right you are! In this case, I'd say that there is no difference. As you correctly mention: the body tag is before the script, and that means it gets parsed first. Your html file has no idea there is any javascript until it has fully parsed the preceding code, and therefore defer does nothing.
Defer's only job is to run JavaScript after all the html has been parsed: see the MDN docs.
That said, with slightly different code, with say, another <script /> underneath is where the difference is found. That second (or more) <script /> tag will then begin to download in parallel (but executed in order). For example:
<script src="script1.js" />
<script src="script2.js" />
script1 is downloaded first, blocking script2 from downloading.
<script src="script1.js" defer />
<script src="script2.js" defer />
script1 is starts to download, then script2 also starts to download in parallel — but — script1 still gets executed in first, even if script2 finishes downloading first.
Further reading:
Detailed stackoverfow answer on script execution order in html
W3Schools description for <script /> (& it's attributes) in html
MDN docs on defer
Hope this helps!
Practically there will be no difference between these two.
Except that document.write (which shouldn't be used anyways) obviously is not allowed in defer.
Technically those are different. So the difference between a script having defer and one that does not, is that the one with defer is executed once the DOM is fully loaded, and the one without at the time where it is loaded.
This can make a difference if the client received the <script src="https://foo/bar.js" defer></script> tag, but the rest of the document is for some reason delayed due to whatever reason. The defer script can only execute if the complete response is sent.
But if that happens then you have other problems anyway.

Should I use defer on script which are already at just before the bottom body tag?

This question has always bothered me every time I put my js files at the bottom of the page. if I put all js files at the bottom before the closing body tag then I think that the browser will first download all the html and style sheets then it will parse the html and css and at last it will send requests for js files. So,
Would using defer on js files which are already at the bottom make any difference?
Are non deferred scripts at the end just before body tag render blocking?
Another question I have is if I put all js file in the head and use defer on them. Would this be equivalent to placing all js files at the bottom? Would seeing js with defer in head the browser make request to the server and then continue downloading rest of html file or will it make request to server only after downloading all html and css?
As far as I know async is equivalent to defer and the only difference is the js will be executed when downloaded without respecting the order of files. So,
Would using async on js files which are already at the bottom make any difference except from the order in which they are executed?
Looking through the HTML 5.2 spec for Scripting, one finds this illustration W3C uses.
What we see here is that using defer fetches the script while the HTML is being parsed, but waits until parsing is concluded before executing.
async, on the other hand, fetches alongside parsing, and once the fetch is complete, HTML rendering is paused to execute the script.
Since HTML execution is synchronous, one can assume that using defer on scripts placed just before </head> would be almost like placing them just before </body>.
However, as Chris Moschini states, I would not trust defer. I feel this StackOverflow answer as a whole would better explain how defer affects loading JavaScripts.
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).
This post I found explains it well: https://flaviocopes.com/javascript-async-defer/
Ideally, the best practice is to have <script defer... in . If you use a CDN, for example, this allows the script to be downloaded while the HTML is being parsed.

Gateway Timeouts and Browser Rendering

If my browser makes a GET to a script src which is currently having a gateway timeout aka 504, why does the browser hang and stop rendering until the response is actually delivered 60 seconds later? Aside from crashing the browser, isn't this the worst thing that could happen to a production javascript application? Is there anything you can do as the app dev to prevent this from blocking the rest of the rendering and script execution?
If the script is inline (e.g. not dynamically loaded) and not marked defer or async, then the script must be processed synchronously in order and the browser cannot proceed without it. Inline <script> tags (without any special attributes) are processed in order as encountered and the browser MUST process them that way.
If you want your page to render without waiting for the script to load, then you can either load it dynamically or you can mark it async or put the <script> tag right before the </body> tag and the page rendering will not wait for it. If using defer or async, you must make sure that no other scripts are dependent upon the loading of this script, otherwise they might run before this one loads.
See these references for more info:
load and execute order of scripts
Script Tag - async & defer
If you are talking about javascript in the DOM within script tags, browsers will always load them synchronously which is why it is important to have the bulk of your JS at the bottom of the page. If this becomes a big issue I would recommend using using an async loading library such as lab.js http://labjs.com/.
If you are getting into more advanced JS and want to utilize something like the AMD pattern for script loading and dependencies you can use http://requirejs.org/.

Scripts with asyc attribute still block other script execution

NOTE: I didn't develop this site - I just have to deal with it.
I have a document with LAB.js being used to asynchronously load a series of scripts in the head. Further down I have two more external scripts, one further down in the head, and the other at the top of the body.
Those two scripts are often unreachable. They're both marked as 'async' and don't block the document from loading. HOWEVER - they do evidently block the other scripts from executing.
To be clear, the first series of scripts are downloaded immediately, but won't seem to execute until the other two async scripts are downloaded.
The site isn't public, and this type of issue can't be created in jsfiddle. A crude illustration:
<!doctype html>
<head>
<!-- This script asynchronously loads many others -->
<script src="/js/LAB.js"></script>
<script src="slow-server/js/slowscript1.js" async></script>
</head>
<body>
<script src="show-server/js/slowscript2.js" async></script>
</body>
Info on Lab.js: http://labjs.com/
LAB will prepend several other script tags to the head to be loaded asynchronously. They're all downloaded right away, but will not execute until the "slow-server" scripts respond. Sometimes takes a while. This seems to me incorrect behavior for scripts with the async attribute (and I'm testing in Chrome). Is there something I'm missing?
From this MDN page:
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.
So, when a script has async, it will be fetched immediately from the server, but DOM parsing will continue in parallel. That part is easy and clear.
Then, as soon as the async script has been fetched, it will be executed. This execution may be before or after the DOM has finished loading depending purely upon timing of how things took to load/parse and it may be before or after other non-async scripts in the page have run.
Note, that because javascript in a browser is single threaded, once this async script starts to execute, no other scripts will run until this script finishes, even though it was "async". Async on the scripts allows the parsing of the DOM to continue (rather than block), but it does not keep the script from executing once it is available and once it executes, other processing has to wait for it to complete executing.
If you want the script to NOT execute until after the DOM and any regular scripts in the DOM have loaded and run, then you should use "defer", not "async".
FYI, if you want to wade through the actual specifications for all this it's here.
If you want a more detailed explanation of how all this applies to your exact situation, you will have to at least give us a pseudo-code representation of what scripts you're asking about as your words aren't clear enough to follow.

Where should I put <script> tags in HTML markup?

When embedding JavaScript in an HTML document, where is the proper place to put the <script> tags and included JavaScript? I seem to recall that you are not supposed to place these in the <head> section, but placing at the beginning of the <body> section is bad, too, since the JavaScript will have to be parsed before the page is rendered completely (or something like that). This seems to leave the end of the <body> section as a logical place for <script> tags.
So, where is the right place to put the <script> tags?
(This question references this question, in which it was suggested that JavaScript function calls should be moved from <a> tags to <script> tags. I'm specifically using jQuery, but more general answers are also appropriate.)
Here's what happens when a browser loads a website with a <script> tag on it:
Fetch the HTML page (e.g. index.html)
Begin parsing the HTML
The parser encounters a <script> tag referencing an external script file.
The browser requests the script file. Meanwhile, the parser blocks and stops parsing the other HTML on your page.
After some time the script is downloaded and subsequently executed.
The parser continues parsing the rest of the HTML document.
Step #4 causes a bad user experience. Your website basically stops loading until you've downloaded all scripts. If there's one thing that users hate it's waiting for a website to load.
Why does this even happen?
Any script can insert its own HTML via document.write() or other DOM manipulations. This implies that the parser has to wait until the script has been downloaded and executed before it can safely parse the rest of the document. After all, the script could have inserted its own HTML in the document.
However, most JavaScript developers no longer manipulate the DOM while the document is loading. Instead, they wait until the document has been loaded before modifying it. For example:
<!-- index.html -->
<html>
<head>
<title>My Page</title>
<script src="my-script.js"></script>
</head>
<body>
<div id="user-greeting">Welcome back, user</div>
</body>
</html>
JavaScript:
// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});
Because your browser does not know my-script.js isn't going to modify the document until it has been downloaded and executed, the parser stops parsing.
Antiquated recommendation
The old approach to solving this problem was to put <script> tags at the bottom of your <body>, because this ensures the parser isn't blocked until the very end.
This approach has its own problem: the browser cannot start downloading the scripts until the entire document is parsed. For larger websites with large scripts and stylesheets, being able to download the script as soon as possible is very important for performance. If your website doesn't load within 2 seconds, people will go to another website.
In an optimal solution, the browser would start downloading your scripts as soon as possible, while at the same time parsing the rest of your document.
The modern approach
Today, browsers support the async and defer attributes on scripts. These attributes tell the browser it's safe to continue parsing while the scripts are being downloaded.
async
<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>
Scripts with the async attribute are executed asynchronously. This means the script is executed as soon as it's downloaded, without blocking the browser in the meantime.
This implies that it's possible that script 2 is downloaded and executed before script 1.
According to http://caniuse.com/#feat=script-async, 97.78% of all browsers support this.
defer
<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>
Scripts with the defer attribute are executed in order (i.e. first script 1, then script 2). This also does not block the browser.
Unlike async scripts, defer scripts are only executed after the entire document has been loaded.
(To learn more and see some really helpful visual representations of the differences between async, defer and normal scripts check the first two links at the references section of this answer)
Conclusion
The current state-of-the-art is to put scripts in the <head> tag and use the async or defer attributes. This allows your scripts to be downloaded ASAP without blocking your browser.
The good thing is that your website should still load correctly on the 2% of browsers that do not support these attributes while speeding up the other 98%.
References
async vs defer attributes
Efficiently load JavaScript with defer and async
Remove Render-Blocking JavaScript
Async, Defer, Modules: A Visual Cheatsheet
Just before the closing body tag, as stated on Put Scripts at the Bottom:
Put Scripts at the Bottom
The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.
Non-blocking script tags can be placed just about anywhere:
<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
async script will be executed asynchronously as soon as it is available
defer script is executed when the document has finished parsing
async defer script falls back to the defer behavior if async is not supported
Such scripts will be executed asynchronously/after document ready, which means you cannot do this:
<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
* might throw "jQuery is not defined" error
* defer will not work either
-->
Or this:
<script src="document.write(something).js" async></script>
<!--
* might issue "cannot write into document from an asynchronous script" warning
* defer will not work either
-->
Or this:
<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
* might throw "jQuery is not defined" error (no guarantee which script runs first)
* defer will work in sane browsers
-->
Or this:
<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
* might not locate #header (script could fire before parser looks at the next line)
* defer will work in sane browsers
-->
Having said that, asynchronous scripts offer these advantages:
Parallel download of resources:
Browser can download stylesheets, images and other scripts in parallel without waiting for a script to download and execute.
Source order independence:
You can place the scripts inside head or body without worrying about blocking (useful if you are using a CMS). Execution order still matters though.
It is possible to circumvent the execution order issues by using external scripts that support callbacks. Many third party JavaScript APIs now support non-blocking execution. Here is an example of loading the Google Maps API asynchronously.
The standard advice, promoted by the Yahoo! Exceptional Performance team, is to put the <script> tags at the end of the document's <body> element so they don't block rendering of the page.
But there are some newer approaches that offer better performance, as described in this other answer of mine about the load time of the Google Analytics JavaScript file:
There are some great slides by Steve Souders (client-side performance expert) about:
Different techniques to load external JavaScript files in parallel
their effect on loading time and page rendering
what kind of "in progress" indicators the browser displays (e.g. 'loading' in the status bar, hourglass mouse cursor).
The modern approach is using ES6 'module' type scripts.
<script type="module" src="..."></script>
By default, modules are loaded asynchronously and deferred. i.e. you can place them anywhere and they will load in parallel and execute when the page finishes loading.
Further reading:
The differences between a script and a module
The execution of a module being deferred compared to a script(Modules are deferred by default)
Browser Support for ES6 Modules
If you are using jQuery then put the JavaScript code wherever you find it best and use $(document).ready() to ensure that things are loaded properly before executing any functions.
On a side note: I like all my script tags in the <head> section as that seems to be the cleanest place.
<script src="myjs.js"></script>
</body>
The script tag should always be used before the body close or at the bottom in HTML file.
The Page will load with HTML and CSS and later JavaScript will load.
Check this if required:
http://stevesouders.com/hpws/rule-js-bottom.php
The best place to put <script> tag is before closing </body> tag, so the downloading and executing it doesn't block the browser to parse the HTML in document,
Also loading the JavaScript files externally has its own advantages like it will be cached by browsers and can speed up page load times, it separates the HTML and JavaScript code and help to manage the code base better.
But modern browsers also support some other optimal ways, like async and defer to load external JavaScript files.
Async and Defer
Normally HTML page execution starts line by line. When an external JavaScript <script> element is encountered, HTML parsing is stopped until a JavaScript is download and ready for execution. This normal page execution can be changed using the defer and async attribute.
Defer
When a defer attribute is used, JavaScript is downloaded parallelly with HTML parsing, but it will be execute only after full HTML parsing is done.
<script src="/local-js-path/myScript.js" defer></script>
Async
When the async attribute is used, JavaScript is downloaded as soon as the script is encountered and after the download, it will be executed asynchronously (parallelly) along with HTML parsing.
<script src="/local-js-path/myScript.js" async></script>
When to use which attributes
If your script is independent of other scripts and is modular, use async.
If you are loading script1 and script2 with async, both will run
parallelly along with HTML parsing, as soon as they are downloaded
and available.
If your script depends on another script then use defer for both:
When script1 and script2 are loaded in that order with defer, then script1 is guaranteed to execute first,
Then script2 will execute after script1 is fully executed.
Must do this if script2 depends on script1.
If your script is small enough and is depended by another script
of type async then use your script with no attributes and place it above all the async scripts.
Reference: External JavaScript JS File – Advantages, Disadvantages, Syntax, Attributes
It turns out it can be everywhere.
You can defer the execution with something like jQuery so it doesn't matter where it's placed (except for a small performance hit during parsing).
The most conservative (and widely accepted) answer is "at the bottom just before the ending tag", because then the entire DOM will have been loaded before anything can start executing.
There are dissenters, for various reasons, starting with the available practice to intentionally begin execution with a page onload event.
It depends. If you are loading a script that's necessary to style your page / using actions in your page (like click of a button) then you better place it at the top. If your styling is 100% CSS and you have all fallback options for the button actions then you can place it at the bottom.
Or the best thing (if that's not a concern) is you can make a modal loading box, place your JavaScript code at the bottom of your page and make it disappear when the last line of your script gets loaded. This way you can avoid users using actions in your page before the scripts are loaded. And also avoid the improper styling.
Including scripts at the end is mainly used where the content/ styles of the web page is to be shown first.
Including the scripts in the head loads the scripts early and can be used before the loading of the whole web page.
If the scripts are entered at last the validation will happen only after the loading of the entire styles and design which is not appreciated for fast responsive websites.
You can add JavaScript code in an HTML document by employing the dedicated HTML tag <script> that wraps around JavaScript code.
The <script> tag can be placed in the <head> section of your HTML, in the <body> section, or after the </body> close tag, depending on when you want the JavaScript to load.
Generally, JavaScript code can go inside of the document <head> section in order to keep them contained and out of the main content of your HTML document.
However, if your script needs to run at a certain point within a page’s layout — like when using document.write to generate content — you should put it at the point where it should be called, usually within the <body> section.
Depending on the script and its usage the best possible (in terms of page load and rendering time) may be to not use a conventional <script>-tag per se, but to dynamically trigger the loading of the script asynchronously.
There are some different techniques, but the most straightforward is to use document.createElement("script") when the window.onload event is triggered. Then the script is loaded first when the page itself has rendered, thus not impacting the time the user has to wait for the page to appear.
This naturally requires that the script itself is not needed for the rendering of the page.
For more information, see the post Coupling async scripts by Steve Souders (creator of YSlow, but now at Google).
Script blocks DOM load until it's loaded and executed.
If you place scripts at the end of <body>, all of the DOM has a chance to load and render (the page will "display" faster). <script> will have access to all of those DOM elements.
On the other hand, placing it after the <body> start or above will execute the script (where there still aren't any DOM elements).
You are including jQuery which means you can place it wherever you wish and use .ready().
You can place most of <script> references at the end of <body>.
But if there are active components on your page which are using external scripts, then their dependency (.js files) should come before that (ideally in the head tag).
The best place to write your JavaScript code is at the end of the document after or right before the </body> tag to load the document first and then execute the JavaScript code.
<script> ... your code here ... </script>
</body>
And if you write in jQuery, the following can be in the head document and it will execute after the document loads:
<script>
$(document).ready(function(){
// Your code here...
});
</script>
If you still care a lot about support and performance in Internet Explorer before version 10, it's best to always make your script tags the last tags of your HTML body. That way, you're certain that the rest of the DOM has been loaded and you won't block and rendering.
If you don't care too much any more about in Internet Explorer before version 10, you might want to put your scripts in the head of your document and use defer to ensure they only run after your DOM has been loaded (<script type="text/javascript" src="path/to/script1.js" defer></script>). If you still want your code to work in Internet Explorer before version 10, don't forget to wrap your code in a window.onload even, though!
I think it depends on the webpage execution.
If the page that you want to display can not displayed properly without loading JavaScript first then you should include the JavaScript file first.
But if you can display/render a webpage without initially download JavaScript file, then you should put JavaScript code at the bottom of the page. Because it will emulate a speedy page load, and from a user's point of view, it would seems like that the page is loading faster.
Always, we have to put scripts before the closing body tag expect some specific scenario.
For Example :
`<html> <body> <script> document.getElementById("demo").innerHTML = "Hello JavaScript!"; </script> </body> </html>`
Prefer to put it before the </body> closing tag.
Why?
As per the official doc: https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics#a_hello_world!_example
Note: The reason the instructions (above) place the element
near the bottom of the HTML file is that the browser reads code in the
order it appears in the file.
If the JavaScript loads first and it is supposed to affect the HTML
that hasn't loaded yet, there could be problems. Placing JavaScript
near the bottom of an HTML page is one way to accommodate this
dependency. To learn more about alternative approaches, see Script
loading strategies.

Categories