JavaScript - head, body or jQuery?
Asked Answered
H

3

64

This question is just to clear some things up. Some things like this have been asked before, and this rounds them all up into one question - where should JavaScript go in the HTML document, or, more importantly, does it matter? So, one of the things I'm asking is, does

<head>
<script type="text/javascript">
alert("Hello world!");
</script>
</head>

at all differ (in terms of functionality) from

<body>
<!-- Code goes here -->
<script type="text/javascript">
alert("Hello world!");
</script>
</body>

More importantly, I want to focus on JS that modifies or uses elements from the DOM in any way. So I know that if you put something like document.getElementById("test").innerHTML = "Hello world!" before <element id="test"></element> in your body, then it won't work since the body is loaded from top to bottom, making the JS load first, which will then proceed to try to manipulate an element that doesn't exist yet. So it should, just like the above, either go in the <head> or just before the </body> tag. The question is, aside from organisation and sorting, does it matter which one of these is chosen, and if so, in what way?

Of course, there is also a third method - the jQuery way:

$(document).ready(function(){ /*Code goes here*/ });

That way, it doesn't matter where in the body you place the code, since it will only be executed when everything has loaded. The question here is, is it worth importing a huge JS library just to use a method the need for which could be replaced with an accurate placing of your scripts? I'd just like to clear things up a little here, if you would like to answer, go ahead! Summary: where should different kinds of scripts go - head or body, and/or does it matter? Is jQuery worth it just for the ready event?

Haeckel answered 12/6, 2012 at 10:0 Comment(4)
So the question Where should I declare JavaScript files used in my page? In <head></head> or near </body>? did not clarify it for you? And in any case, if you are interested in the functionality of ready you can just have a look at the source code and replicate it if needed.Dowell
Your "jQuery method" can be accomplished with native JavaScript: window.onload = function(){} -- No library neededCasandra
@Felix - :O sorry for that, must have missed it. Also, since I'm asking this question, you could have figured out I'm a bit of a noob at JS, so I can't really imagine myself trying to plough through the jQuery source code :PHaeckel
@all the answers - so you're saying that putting scripts in the head slows down the loading of the page; does that mean that if I have lots and lots of JS I should put it just before the </body>, and if I have a couple of lines I can slot it in the head, since that won't slow it down too much?Haeckel
P
62

Most recommended method is to put it before </body> tag. Yahoo performance article also suggests that other than YSlow and Page Speed addons by Yahoo and Google respectively.

Quoting from Yahoo article linked above:

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.

When you put scripts in <head> tag, the browsers goes for them thereby keeping other stuff on hold until scripts are loaded which users will perceive like slow loading of the page. This is why you should put scripts at the bottom.

As for:

$(document).ready(function(){/*Code goes here*/});

It is fired when DOM is available and ready to be manipulated. If you put your code at the end, you won't necessarily need this but usually this is needed because you want to do something as soon as DOM is available for use.

Psych answered 12/6, 2012 at 10:3 Comment(3)
This is a great answer, but what should you do if you need to use something like $("td.speical-format").live() on a table that comes before you include jquery?Entrance
If you are going to put it last, then always use a spinner/loader.. this is because if your css/js is large or large in numbers then some of the things dependent on jquery will not work...Thundersquall
as per your point, your saying we should download the JS library files also at the bottom. unless we use async, it will be a render blocking JavaScript. But JS library files should be ready when the painting process is completed for the custom JavaScript (ex: document.ready()) to run their functions isnt it?Cesar
B
29

Although common practice, putting script tags in the head is not usually a good idea, as it holds up the rendering of your page until those scripts have been downloaded and processed (barring your use of async or defer and the browser supporting them).

The usual recommendation is to put script tags at the very end of the body tag, e.g., just before </body>. That way, all of the DOM elements above the script will be accessible (see links below). One caveat on that is that there can be a brief moment when your page has been at least partially-rendered but your scripts not processed (yet), and if the user starts interacting with the page, they may do something to raise an event that your script hasn't had time to hook yet. So you need to be aware of that. This is one reason for progressive enhancement, which is the idea that the page will work without JavaScript, but work better with it. If you're doing a page/app that just won't work without JavaScript at all, you might include some inline script at the top of the body tag (e.g., <script>minimal code here</script>) that hooks any bubbling events on document.body and either queues them for action when your script is loaded, or just asks the user to wait.

Using features like jQuery's ready is fine, but not really necessary outside of libraries (e.g., if you're in control of where the script tags will be, you don't usually need to use it; but if you're writing a jQuery plug-in that needs to do something on load [which is relatively rare, normally they just wait to be called], you usually do).

More reading:

Barbabas answered 12/6, 2012 at 10:5 Comment(4)
So if I'm making an app to which JS in integral, I should use an inline hook; what about if one is making a Chrome extension (where inline JS is not allowed)?Haeckel
@Bluefire: I didn't say you should, just that it would be one way to defend against that brief interval. Are you saying you can't do <script>code here</script> in a Chrome extension?Barbabas
No :D I'm saying you can't do stuff like <span oncick="yourEvent()"></span>. I thought that's what you meant by "inline".Haeckel
@Bluefire: Ah, sorry, I meant inline as in a script element that directly contains its code rather than referring to a separate script file.Barbabas
W
7

It is possible to download javascripts in parallel by doing something like this:

(function () {
    var ele = document.createElement('script');
    ele.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js";
    ele.id = "JQuery";
    ele.onload = function () {
        //code to be executed when the document has been loaded
    };
    document.getElementsByTagName('head')[0].appendChild(ele);
})();

In the example it downloads minified JQuery v1.7.2 from Google, this is a good way to download JQuery since downloading it from Google is like using a CDN and if the user has been on a page that used the same file it might be cached and therefor doesn't need to be downloaded

There is a really good Google tech talk about this here http://www.youtube.com/watch?v=52gL93S3usU&feature=plcp

Wyant answered 12/6, 2012 at 10:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.