Issue of javascript loading - javascript

First question:
About Dynamic Script Elements
var script = document.createElement ("script");
script.type = "text/javascript";
script.src = "script.js"; document.getElementsByTagName_r("head")[0].appendChild(script);
The important thing about this technique is that the file is downloaded and executed without blocking other page processes, regardless of where the download is initiated. You can even place this code in the <head> of a document without affecting the rest of the page.
I want to know what is difference between Dynamic Script Elements and this codes
<script type="text/javascript" src="script.js"></script>
Why does Dynamic Script Elements download and execute file without blocking other page processes and the other will?
Second question:
I know that the page download and rendering must stop and wait for the script to complete before proceeding, so I put scripts at the bottom before </body>
Is it necessary to use XMLHttpRequest Script Injection or other libraries like lazyload when I put scripts at the bottom, and why?
Anybody know this? Thanks

I want to know what is difference between Dynamic Script Elements and
this codes
Your code snippet is a dynamic script element. It is added dynamically to the page and is not natively present in the HTML of the page.
Script tags present in the HTML of the page are executed sequentially as the browser encounters them during the parsing of the page. The first script element is executed before any others, then the second and so on. Because there can be script elements embedded anywhere in the HTML of the page and they must execute in sequential order, a script element in the page must load and be executed before the rest of the HTML after it can be parsed and added to the page.
Why does Dynamic Script Elements download and execute file without
blocking other page processes and the other will?
I'm not sure what kind of answer you're looking for here. It works this way because this is how the designers of the browser/HTML specs decided it would work. A dynamically added script executes asynchronously, independent of the loading of the page. A script element present in the HTML of the page executes in a predictable order with respect to both other scripts and with respect to the loading of the page elements. This can be very important for some types of scripts (such as document.write() and thus the designers of these specs allow you to have either predictable, sequential order (which by its very nature must block until complete) or asynchronous loading. The defer and async attributes also allow you to change the behavior of even script tags that are present in the HTML of the page. So, this way you can have whichever behavior is most advantageous.
Is it necessary to use XMLHttpRequest Script Injection or other
libraries like lazyload when I put scripts at the bottom, and why?
No, it is not necessary to use script injection. Putting a script at the bottom of the page will allow the page elements above it to show to the user without waiting for the script to execute (if that is your goal). There are many other reasons for dynamically loading scripts besides just page load performance. For example, some scripts are loaded only when needed based on what action the page is going to execute.
For a lot more info about the execution order of scripts including the effect of the defer and async attributes in script tags, see this detailed post: load and execute order of scripts

The position of the script tags has something historical. In the early easy was often document.write() used to the Dom could change that is why a script block can block the rendering. However there is a attribute which says I don't change the Dom go on.
Script tags at the end of the page are related to the time when the download process is triggered so this can optimize the load process.
That lazyload libs are helpful of you need some other frameworks/libs only under some runtime conditions. It's all about page load times and how fast the page react on user interactions.

Related

Question about Javascript code execution speed regarding the order in which their file are declared [duplicate]

There are so many different ways to include JavaScript in a html page. I know about the following options:
inline code or loaded from external URI
included in <head> or <body> tag [1,2]
having none, defer or async attribute (only external scripts)
included in static source or added dynamically by other scripts (at different parse states, with different methods)
Not counting browserscripts from the harddisk, javascript:URIs and onEvent-attributes [3], there are already 16 alternatives to get JS executed and I'm sure I forgot something.
I'm not so concerned with fast (parallel) loading, I'm more curious about the execution order (which may depend on loading order and document order). Is there a good (cross-browser) reference that covers really all cases? E.g. http://www.websiteoptimization.com/speed/tweak/defer/ only deals with 6 of them, and tests mostly old browsers.
As I fear there's not, here is my specific question: I've got some (external) head scripts for initialisation and script loading. Then I've got two static, inline scripts in the end of the body. The first one lets the script loader dynamically append another script element (referencing external js) to the body. The second of the static, inline scripts wants to use js from the added, external script. Can it rely on the other having been executed (and why :-)?
If you aren't dynamically loading scripts or marking them as defer or async, then scripts are loaded in the order encountered in the page. It doesn't matter whether it's an external script or an inline script - they are executed in the order they are encountered in the page. Inline scripts that come after external scripts are held until all external scripts that came before them have loaded and run.
Async scripts (regardless of how they are specified as async) load and run in an unpredictable order. The browser loads them in parallel and it is free to run them in whatever order it wants.
There is no predictable order among multiple async things. If one needed a predictable order, then it would have to be coded in by registering for load notifications from the async scripts and manually sequencing javascript calls when the appropriate things are loaded.
When a script tag is inserted dynamically, how the execution order behaves will depend upon the browser. You can see how Firefox behaves in this reference article. In a nutshell, the newer versions of Firefox default a dynamically added script tag to async unless the script tag has been set otherwise.
A script tag with async may be run as soon as it is loaded. In fact, the browser may pause the parser from whatever else it was doing and run that script. So, it really can run at almost any time. If the script was cached, it might run almost immediately. If the script takes awhile to load, it might run after the parser is done. The one thing to remember with async is that it can run anytime and that time is not predictable.
A script tag with defer waits until the entire parser is done and then runs all scripts marked with defer in the order they were encountered. This allows you to mark several scripts that depend upon one another as defer. They will all get postponed until after the document parser is done, but they will execute in the order they were encountered preserving their dependencies. I think of defer like the scripts are dropped into a queue that will be processed after the parser is done. Technically, the browser may be downloading the scripts in the background at any time, but they won't execute or block the parser until after the parser is done parsing the page and parsing and running any inline scripts that are not marked defer or async.
Here's a quote from that article:
script-inserted scripts execute asynchronously in IE and WebKit, but
synchronously in Opera and pre-4.0 Firefox.
The relevant part of the HTML5 spec (for newer compliant browsers) is here. There is a lot written in there about async behavior. Obviously, this spec doesn't apply to older browsers (or mal-conforming browsers) whose behavior you would probably have to test to determine.
A quote from the HTML5 spec:
Then, the first of the following options that describes the situation
must be followed:
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 task that the networking task source places on the task queue once
the fetching algorithm has completed must set the element's "ready to
be parser-executed" flag. The parser will handle executing the script.
If the element has a src attribute, and the element has been flagged
as "parser-inserted", and the element does not have an async attribute
The element is the pending parsing-blocking script of the Document of
the parser that created the element. (There can only be one such
script per Document at a time.)
The task that the networking task source places on the task queue once
the fetching algorithm has completed must set the element's "ready to
be parser-executed" flag. The parser will handle executing the script.
If the element does not have a src attribute, and the element has been
flagged as "parser-inserted", and the Document of the HTML parser or
XML parser that created the script element has a style sheet that is
blocking scripts The element is the pending parsing-blocking script of
the Document of the parser that created the element. (There can only
be one such script per Document at a time.)
Set the element's "ready to be parser-executed" flag. The parser will
handle executing the script.
If the element has a src attribute, does not have an async attribute,
and does not have the "force-async" flag set The element must be added
to the end of the list of scripts that will execute in order as soon
as possible associated with the Document of the script element at the
time the prepare a script algorithm started.
The task that the networking task source places on the task queue once
the fetching algorithm has completed must run the following steps:
If the element is not now the first element in the list of scripts
that will execute in order as soon as possible to which it was added
above, then mark the element as ready but abort these steps without
executing the script yet.
Execution: Execute the script block corresponding to the first script
element in this list of scripts that will execute in order as soon as
possible.
Remove the first element from this list of scripts that will execute
in order as soon as possible.
If this list of scripts that will execute in order as soon as possible
is still not empty and the first entry has already been marked as
ready, then jump back to the step labeled execution.
If the element has a src attribute The element must be added to the
set of scripts that will execute as soon as possible of the Document
of the script element at the time the prepare a script algorithm
started.
The task that the networking task source places on the task queue once
the fetching algorithm has completed must execute the script block and
then remove the element from the set of scripts that will execute as
soon as possible.
Otherwise The user agent must immediately execute the script block,
even if other scripts are already executing.
What about Javascript module scripts, type="module"?
Javascript now has support for module loading with syntax like this:
<script type="module">
import {addTextToBody} from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
Or, with src attribute:
<script type="module" src="http://somedomain.com/somescript.mjs">
</script>
All scripts with type="module" are automatically given the defer attribute. This downloads them in parallel (if not inline) with other loading of the page and then runs them in order, but after the parser is done.
Module scripts can also be given the async attribute which will run inline module scripts as soon as possible, not waiting until the parser is done and not waiting to run the async script in any particular order relative to other scripts.
There's a pretty useful timeline chart that shows fetch and execution of different combinations of scripts, including module scripts here in this article: Javascript Module Loading.
A great summary by #addyosmani
Shamelessly copied from https://addyosmani.com/blog/script-priorities/
The browser will execute the scripts in the order it finds them. If you call an external script, it will block the page until the script has been loaded and executed.
To test this fact:
// file: test.php
sleep(10);
die("alert('Done!');");
// HTML file:
<script type="text/javascript" src="test.php"></script>
Dynamically added scripts are executed as soon as they are appended to the document.
To test this fact:
<!DOCTYPE HTML>
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
var s = document.createElement('script');
s.type = "text/javascript";
s.src = "link.js"; // file contains alert("hello!");
document.body.appendChild(s);
alert("appended");
</script>
<script type="text/javascript">
alert("final");
</script>
</body>
</html>
Order of alerts is "appended" -> "hello!" -> "final"
If in a script you attempt to access an element that hasn't been reached yet (example: <script>do something with #blah</script><div id="blah"></div>) then you will get an error.
Overall, yes you can include external scripts and then access their functions and variables, but only if you exit the current <script> tag and start a new one.
After testing many options I've found that the following simple solution is loading the dynamically loaded scripts in the order in which they are added in all modern browsers
loadScripts(sources) {
sources.forEach(src => {
var script = document.createElement('script');
script.src = src;
script.async = false; //<-- the important part
document.body.appendChild( script ); //<-- make sure to append to body instead of head
});
}
loadScripts(['/scr/script1.js','src/script2.js'])
I had trouble understanding how to get an embedded module-script to execute before the onload event happens. The answers above helped a lot but let me add a partial answer about what fixed my particular problem of misunderstanding the "Load and execute order of scripts".
I first used ... which caused an odd problem that it worked when loading the page normally, but not when running it in debugger on FireFox. That made debugging very difficult.
Note: Scripts whose type is "module" always have an implicit "deferred" attribute which means they don't stop the parsing of html, which means the onload-event can happen before the script gets executed. I did not want that. But I did want to use type="module" to make my un-exported JavaScript functions and variables invisible to other scripts on the same page.
I tried different options but thanks to the above answers I gained the insight that if you add the async -attribute to a script of type module it means that the script loads asynchronously BUT once it is loaded it executes immediately.
But in my case this was a script embedded in an HTML page. THEREFORE it meant nothing needed to load "asynchronously". It was already loaded with the page, since it was embedded in it. Therefore it with this change did get executed immediately -- which is what I wanted.
So I think it is worthwhile to point out this specific case because it is somewhat counter-intuitive: To get an embedded script executed IMMEDIATELY you must add the ASYNC attribute to its tag.
Ordinarily one might think that "async" means something happens asynchronously, in indeterminate order, not immediately. But the thing to realize is that "async" causes asynchronous LOADING, but immediate EXECUTION after the loading is complete. And when the script is embedded, no loading needs to be done, and therefore you get immediate execution.
Summary: Use
<script type="module" async> ... </script>
to get a module-script embedded to an HTML-page to execute immediately.
Perfect match for your query!
If none of the solutions worked for you then please refer to the below solution of mine which I have developed from my side.
I was also looking for the solution but after searching a lot, I summarized my code as below which is working perfectly for me!!
This is useful when you want functionality such that after previous script has fully loaded then and then only load next script!
just create a file named jsLoadScripts.js and insert it into the head or at the bottom of the body.
//From Shree Aum Software Solutions
//aumsoftwaresolutions#gmail.com
//script incrementor for array
scriptIncrementor = 0;
//define your script urls here
let scripts = [
"https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js",
"jsGlobalFunctions.js",
"jsDateParser.js",
"jsErrorLogger.js",
"jsGlobalVariables.js",
"jsAjaxCalls.js",
"jsFieldsValidator.js",
"jsTableClickEvent.js",
"index.js",
"jsOnDocumentReady.js",
];
//it starts with the first script and then adds event listener to it. which will load another script on load of it. then this chain goes on and on by adding dynamic event listeners to the next scripts!
function initializeScripts() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = scripts[scriptIncrementor];
document.head.appendChild(script);
script.addEventListener("load", function () {
loadNextScript();
scriptIncrementor++;
});
}
// this function adds event listener to the scripts passed to it and does not allow next script load until previous one has been loaded!
function loadNextScript() {
if (scriptIncrementor != scripts.length - 1) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = scripts[scriptIncrementor + 1];
document.head.appendChild(script);
script.addEventListener("load", function () {
loadNextScript();
scriptIncrementor++;
});
}
}
// start fetching your scripts
window.onload = function () {
initializeScripts();
};
This may cause you some speed related issues so, you can call function initializeScripts() with your custom needs!

Is it possible to include a specific javascript file on click?

I am currently working on a website that includes several very large Javascript files. These files are causing the load time of the page to become very slow.
The output of the javascript files are initially hidden to the user behind several jquery tabs. I was wondering if it is possible to load the files only when the user clicks on those specific tabs so that the initial load time of the website wouldn't be slow?
Javascript files can be loaded dynamically upon demand when you need them.
This will be an asynchronous operation so you will start the loading process and then some time later the script will be loaded and available to you.
In jQuery, you can use $.getScript().
Example:
$.getScript("test.js", function() {
// script is loaded now
// code that uses this script can go here
});
FYI, there are other techniques for improving the load time of your site. For example, you can put all non-essential scripts (those not involved in the initial display of your page) at the very end of the <body>, right before the </body> tag. This will allow your page to display without waiting for those scripts to load.
Scripts can also be marked async and defer so that other aspects of page loading will NOT wait for them to load.
Other useful references on this topic:
Script Tag - async & defer
Deferred scripts and DOM
load and execute order of scripts
improving website performance by dynamically loading javascript?
Yes you can do this. See
http://community.sitepoint.com/t/dynamically-loading-js-script/40207/15
You will probably have to do some string concatenation in the filename when writing out the src attribute so its loads the different file you require

Two different ways of putting the script at the bottom - what are the differences?

What are the differences between the two solutions below ?
In particular, is there a good reason to favour 2 over 1. (note: Please assume the name of the script to load is known. The question is just about if there is value in creating a minimal script to load a script in the given situation )
1 - Script At The Bottom
<html>
<body>
...
...
<script src='myScript.js'></script>
</body>
</html>
2 - Script at the bottom loads external script
<html>
<body>
...
...
<script>
// minimal script to load another script
var script = document.createElement('script');
script.src = 'myScript.js'
document.body.appendChild(script);
</script>
</body>
</html>
One important feature of the second one is that it allows the browser to finish parsing the page immediately, without waiting for the script to load. That's because the first example allows the script to use document.write to change the parsing state around the <script> tag, while the second one doesn't.
Now, we know that it's at the bottom of the page so that there isn't any important content left to parse, but this is still an important difference. It's not until parsing is done that the browser fires the popular DOMContentLoaded event. In method 1, the event fires after the script loads and executes. In method 2, the event fires before the script starts loading.
Here are some examples. In these demos, a DOMContentLoaded listener changes the background color to yellow. We try to load a script that takes 3 seconds to load.
http://jsfiddle.net/35ccs/
http://jsfiddle.net/VtwUV/
(edit: Maybe jsfiddle wasn't the best place to host these demos. It doesn't show the result until the slow-loading script loads. Be sure to click Run again once it loads, to see what happens.)
Pick the approach that's best for your application. If you know you need the script to run before DOMContentLoaded, go with method 1. Otherwise, method 2 is pretty good in most cases.
1. Script at the bottom
When you use a "synchronous" script tag, it will block the browser from rendering the page until the script is loaded and executed. This method has the following effects:
Regardless of where you put the script tag, the browser cannot fire DOMContentLoaded until the script is downloaded and executed.
Placing such a script tag at the bottom only ensures that the browsers has rendered all content before getting blocked by the script.
2. Script at the bottom loads external script
When you inject a script tag using JavaScript, it will create an "asynchronous" script tag that does not block the browser. This method has the following effects:
Regardless of where you put the JavaScript code that generates the script tag, the browser executes it as soon as it is available without blocking the page. The DOMContentLoaded fires when it should; irrespective of whether the script has downloaded/executed.
The second approach has the following advantages:
The script that injects a script tag can be placed anywhere including document head.
The script will not block the rendering.
DOMContentLoaded event does not wait for the script.
The second approach has the following disadvantages:
You cannot use document.write in such scripts. If you do, such statements might wipe the document clean.
Asynchronous execution does not mean that browser has finished parsing the page. Keep the script executes as soon as it is available clause in mind.
Execution order is not guaranteed. Example: If you load "library.js" and "use-library.js" using injected script tags, it is possible for "use-library.js" to load and execute before "library.js".
Having said all that, there is another method for loading scripts, with three variations:
<script src="myScript.js" async></script>
<script src="myScript.js" defer></script>
<script src="myScript.js" async defer></script>
Regarding Steve Souders's work: he proposed 6 techniques for loading scripts without blocking. The async and defer attributes introduced in HTML5 cover the Script DOM Element and Script Defer techniques and their browser support is more than enough for you to worry about the other techniques.
These two ways of initializing a script are basically the same, although theres no reason to use the second way if you can directly put in the result. However you can wrap the second example in a $(document).ready() method for example which would lead to sort of a lazy loading effect. This basically means that the page would load first and after the loading of the page is finished it would load the script. Or of course you can create a method which initializes a certain script this way. It's useful when you have a large script which is used only in some situations. This would prevent loading it unless you need it, thus decreasing the overall loading time.
This isn't a direct answer to your question, but it's good to know regardless.
The 2nd approach is sometimes used as a library fallback.
For example, you load jQuery from the Google CDN. But, if it were to fail for any reason, load jQuery from your own local copy.
Here's how the popular HTML5 Boilerplate recommends doing this:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.0.min.js"><\/script>')</script>
The first method means that the script tag is hardcoded in. The second method dynamically adds a script tag to the bottom of the page using JavaScript. The benefit of the second method is that you can add additional logic if needed to modify the script tag. Perhaps you might want to load a different script file based on culture, browser or some other factor you can determine in JavaScript. The second method also causes the JavaScript file to be loaded without blocking the loading of the rest of the web page. In method one the page will stop loading when it gets to the script tag, load the JavaScript file, then finish loading the rest of the page. Since this tag is at the bottom of your page it doesn't make too much of a difference.
If you are creating a Windows Store app using JavaScript then the first method is recommended as this will allow the app to bytecode cache the JavaScript file which will make it load up faster.

Javascript non-blocking scripts, why don't simply put all scripts before </body> tag?

In order to avoid javascript to block webpage rendering, can't we just put all all our JS files/code to be loaded/executed simply before the closing </body> tag?
All JS files and code would be downloaded and executed only after the all page has being rendered, so what's the need for tricks like the one suggested in this article about non blocking techniques to load JS files. He basically suggests to use code like:
document.getElementsByTagName("head")[0].appendChild(script);
in order to defer script laod while letting the webpage to be rendered, thus resulting in fast rendering speed of the webpage.
But without using this type of non-blocking technique (or other similar techniques), wouldn't we achieve the same non-blocking result by simply placing all our JS files (to be loaded/executed) before the closing </body> tag?
I'm even more surprised because the author (in the same article) suggests to put his code before the closing </body> tag (see the "Script placement" section of the article), so he is basically loading the scripts before the closing </body> tag anyway. What's the need for his code then?
I'm confused, any help appreciated, thanks!
UPDATE
FYI Google Analytics is using similar non-blocking technique to load their tracking code:
<script type="text/javascript">
...
(function()
{
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = 'your-script-name-here.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s); //why do they insert it before the 1st script instead of appending to body/head could be the hint for another question.
})();
</script>
</head>
Generally saying no. Even if scripts will be loaded after all the content of the page, loading and executing of the scripts will block the page. The reason for that is possibility of presence of write commands in your scripts.
However if all you want to achieve is the speed of loading page contents, the result of placing script tags right before </body> tag is the same as for creating script tags dynamically. The most significant difference is that when you load scripts in common static way they are executed one by one, in other words no parallel execution of script file (in old browsers the same true is for downloading of the script too).
If you want asynchonous scripts.
Use the (HTML5) async tag if it is availble in the browser you're in. This is what Google Analytics is doing in the code you posted (specifically the line ga.async = true MDN Link, scroll down for async).
However, this can cause your script to load at arbitrary times during the page load - which might be undesirable. It's worth asking yourself the following questions before choosing to use async.
Don't need user input? Then using the async attribute.
Need to respond to buttons or navigation? Then you need to put them at the top of the page (in head) and not use the async tag.
Async scripts run in any order, so if your script is depending on (say) jQuery, and jQuery is loaded in another tag, your script might run before the jQuery script does - resulting in errors.
Why don't people put things at the bottom of the body tag? If the script is taking enough time to load that it's slowing/pausing the load of the website, it's quite possible that that script is going to pause/hang the website after the website has loaded (expect different behaviour on different browsers) - making your website appear unresponsive (click on a button and nothing happens). In most cases this is not ideal, which is why the async attribute was invented.
Alternatively if your script is taking a long time to load - you might want to (after testing) minify and concatenate your script before sending it up to the server.
I recommend using require.js for minifying and concatenation, it's easy to get running and to use.
Minifying reduces the amount of data that needs to be downloaded.
Concatenating scripts reduces the number of "round-trips" to the server (for a far away server with 200ms ping, 5 requests takes 1 second).
One advantage of asynchronous loading (especially with something like the analytics snippet) is, at least if you would place it on the top, that it would be loaded as soon as possible without costing any time in rendering the page. So with analytics the chances to actually track a user before he leaves the page (maybe before the page was fully loaded) will be higher.
And the insertBefore is used instead of append, because if I remember correctly there was a bug (I think in some IE versions, see also link below theres something in the comments about that).
For me this link:
Async JS
was the most useful I found so far. Especially because it also brings up the issue, that even with googles analytic code the onload event will still be blocked (at least in some browsers). If you want this to not happen, better attach the function to the onload event.
For putting the asynchronous snippet on the bottom, that is actually explained in the link you posted. He seems to just do it to make sure that the DOM is completely loaded without using the onload event. So it may depend on what you're scripts are doing, if you're not manipulating the DOM there should be no reason for adding it on the bottom of body. Besides that, I personally would prefer adding it to the onload-event anyway.

Why are JS scripts usually place in the header of a document?

Why are JS scripts usually place in the header of a document? Is it required by standards, or is it just a convention with no particular reason?
See http://developer.yahoo.com/performance/rules.html#js_bottom
Although past practice has often been to place them in the header for the sake of centralizing scripts and styles (and the like), it is advisable now to place the scripts at the bottom to improve loading speed of the rest of the page.
To quote:
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.
In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.
An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn't support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.
A <script src="url"></script> will
block the downloading of other page
components until the script has been
fetched, compiled, and executed. It is
better to call for the script as late
as possible, so that the loading of
images and other components will not
be delayed.
It depends on what the script is doing. If your code is wrapped in onLoad event then it doesn't matter since it will return almost immediately and not block otherwise you should put it where it fits because the placement does matter.
As for putting it at the end, it does give a little extra time for user to start looking at the page. Just ask yourself a question - does my site work without javascript? If it doesn't, then in my opinion it doesn't mater where you put it since onLoad code will only be executed when the DOM has been fully loaded (that includes binary content like images). If you can use it without javascript then put it at the end so that images can load faster.
Also note that most JS libraries use special code which works around the onLoad problem and uses custom event for this which gets fired once DOM has loaded and doesn't wait for binary data.
Now that I wrote all that, I got a question of my own. Does using say jQuery's
$(document).ready(function () {});
and putting the script tag at the end of page is the same as using onLoad event and putting it at the start?
It should be the same because browser would load all images before loading the script which is the last one in the list. If you know the answer leave a comment (I'm too lazy and it's too late to test it atm).
It's just a convention. It's usually recommended to put scripts at the end of the body so the page can display before loading them, which is always a plus. Also, document.body can't be used until the document is loaded or if you put the script in the body.

Categories

Resources