Why do I get the impression that loading a script and running a script are taken as equivalent for the sake of this conversation? They are not. Loading your script is not any more time consuming than loading any other part of the page that has a similar file size.
Running a script is a totally different issue; it will shut down everything else while it runs. The real issue is why would you have the script run before the DOM is built, anyway? Put an onload event handler in your script; no hoo-hah.
Whether the script link or the stylesheet link appears first macht nichts. However, putting the script at the end of the body element breaks the principle of separation of structure, presentation, and behavior. It is poor practice.
I don’t think it breaks any separations of concerns principle - whether it is in the head or body doesn’t affect whether it is an external script or not. I just like to group all that kind of thing in the head. My concern is mainly that a page starts rendering, the JS changes the layout of the page so everything suddenly moves about… it’s like the old FOUC problem, with U standing for Unscripted instead
So, by the time my DOM comes to download, I would want my scripts already downloaded and waiting to act as soon as they can.
There is a difference philosophically, if not necessarily pragmatically. The head is the part of the document for meta data; the stuff about the document, what the document uses (e.g. scripts and stylesheets) and the relationships among the pieces.
The placement of the script in the html is obtrusive from the standpoint that if you haven’t controlled when and what parts of the script are to run, then where you place it in the document matters. IOW, it’s obtrusive.
OTOH, if you have controlled the run within the script, it should be in the head where it belongs.
I have not had any js problems with IE6/7 other than some general MSFT funkiness due to their non-standard language support. IE understands attaching event handlers, and bubble-up/trickle-down are the few causes of hiccups. I may be missing something, though; I’m no expert with js. I haven’t written anything other than event driven stuff in a long time. I feel that using js to generate content, which I see a lot of, is using the wrong tool. That kind of stuff belongs on the server level, as I always work from the presumption that the user has bare-bones html only. Everything else is candy. So if you want something to appear to your visitor, it should come from the server as html first.
Yeh I do that too, generate an ‘initial state’ with php in the html, style that, and use JS to modify it / add ajax capabilities / whatever. If the JS enabled visitor can use a nicer interface than a non JS user, then I might modify the source quite a lot with JS to enable / make use of the other interface, but it will still work with the inferior interface with JS off.
I still disagree that “in the head” is where it belongs.
I do agree that having a script element randomly placed in the body is a pain to find and maintain, and it shouldn’t be there. However, I think right before the closing body tag is perfectly acceptable and just as easy to maintain as if it’s in the head. And you get a boost in load speed.
Once again, the exception to this is in cases like Stormrider describes where you use JS to heavily change the layout. In these cases I’d put it in the head so you don’t get a random rearrange of the screen.
However, things like click events and other things that don’t appear initially should be in the footer.
But then it always worries me… what if someone tries to click before the script has loaded? Or interact with any element that the script will attach events to.
I do worry about that as well and weigh the pros and cons:
Is this something that is likely to load substantially before the script?
Is this something that will look broken before the script loads?
etc
If it is something I worry about, I will move it above. However, a lot of times they’re things that don’t matter if they’re loaded or not by the time they click them (or they’ll load before they’re able to click them). Most click actions have actions that work without the Javascript as well, just not as perfectly.