head element, and up to now, as far as you know, it has worked just fine for you.
body tag instead.
There are a number of reasons why this way of doing it is attractive:
- There’s no need to have a check if the DOM is loaded, since by having the scripts at the end, you know for sure it is.
It is also a recommended by Yahoo’s Best Practices for Speeding Up Your Web Site: Put Scripts at the Bottom.
I had a site recently that I had included scripts on the bottom, but had to move them within the head because I was using sifr, and sifr has it's own method for checking dom readiness that actually seemed to take longer if the script was included at the bottom.
Aside from that issue though, it worked pretty well. I was able to use a lot of anonymous functions and call them immediately, with no worries about polluting the global namespace.
Yep after the Yahoo! performance team's research I go before the closing body tag.
Already doing this, but thanks for posting!
I'm sure there are others that can benefit from this information.
It seems that you're working on something that require great performance. Thanks for all these posts :] !
Definitely bottom. And stiching of multiple files together when possible. Multiple script tags and http requests are killers. There is also some talk around the poor (or rather, lesser) performance of applying events onload. Hard coding event handlers has performance gains that could trump unobtrusiveness – blasphemy I know, but maybe worth discussion.
Well done. 🙂
Personally, I always put scripts in the head section of the document. I seem to remember something about it being the only place for it, according to the spec, but it's too early in the day to go and hunt for references, or make documents and run them through the validator.
I also remember giving someone else hell for suggesting putting scripts at the bottom of the documents, when the YUI recommendations came out.
Assuming that you can validate documents with scripts anywhere, I guess my sole surviving argument for putting them in the head element, is that it's convention, and other developers will know where to look for them. I realise that conventions change over time, and they should … but this still seems lame … browser vendors (or at least the WebKit team) are already implementing measures to mitigate the slowness of external scripts, by actually parsing external scripts in several threads.
Am I willing to change my documents to use bottom-feeders instead of top-breeders?
I honestly can't say … my current documents validate (mostly), browsers run my scripts just fine, the sites are fast enough. So for my documents, there is no compelling reason to spend clients money or my personal time updating them for a few milliseconds of rendering time.
Am I willing to adopt a new practice, if it turns out to be good, valid, justified? Certainly, I continually look for ways to improve my work.
Are you willing to go back and change all your documents, if/when:
– it turns out to be invalid?
– browsers handle scripts better?
– html5 turns out to not allow scripts all over?
I seem to remember reading somewhere that you can have more than one <head> section in an HTML document. You can, I think, load extra JS in a second <head> section, after the end of the <body> section.
Surely that’s not completely true? Wasn’t the entire point of finding a cross-browser
DOMContentLoadedsimply because putting the script include at the bottom of the page was not sufficient?
One single script tag in the header (respecting specs, as Morgan said) that will include external optimized JS trying to force caching.
The user will wait only the first time (usually an hilarious delay, since I do not use big frameworks and I personally write everything I need).
At this point if I would like to be sure about DOMContentLoaded compatibility, I use the script at the end of the body, calling the "main function", otherwise I usually put everything, again, inside the single optimized JS file 🙂
On the other hand, if we use big frameworks, it should means that our site depends on that FW, so every expected behavior will not be available, using the bottom script strategy.
Accordingly, I guess we should put them in the header, again … using one single optimized script.
P.S. Yahoo best practices? They even do not use external files and put everything in every page in the header … just look into homepage source.
However often users would click before the JS was ready, in particular a big TRADE button. So I devised a click caching system. It's not perfect, it's kinda ugly, but it goes some way towards solving this problem:
My approach is large solutions: foot. Quick small, low traffic solutions, where I like, particularly: head.
@Morgan, @Andrea – It’s not against specs to place script-elements in the body-element.
I’ve put them just before the closing body-tag ever since I heard Nate Koechly’s talk at @media 2007.
I also merge all my JS-files into one as well as compress them using Dean Edward’s JS-compressor.
Interesting Remy, so why don't you separe everything using script tag in the bottom, before others, and a simple snippet like this one?
a = document.getElementsByTagName("a"),
l = a.length;
a[l].onclick = earlyClickHandler
In this case you won't have onclick in layout, so page load until above code will be even faster, if you're using a lot of links. Am I wrong?
@Andreas, but shouldn't you put a noscript after every script?
I am talking about accessibility specs and graceful enhancement, because if your page works only with JS, it does not make sense to show content before JS is usable, imho, user has to wait in both cases for responsiveness.
P.S. Dean's packer is not exactly what I was talking about when I said optimized 🙂
I used to put scripts at the bottom, but moved them back to the head recently.
Reason being, I was using swfobject to write a flash movie into the page and it looked awkward for the whole page to load with a ugly bare content area that was going to be replaced by the swf.
@Andrea – I don't use noscript, i use progressive enhancement. The site will function properly with or without JS.
Also, you _should_ put noscript-elements in the body-element. Otherwise no-one will ever see the contents of them.
"Getting head"!!!! baaaaaahahahahahhahahaha LMFAO!!!!
You, Rob, are definitely THE Rockstar!!! 😀
The only important reason to put scripts at the end of a file appears to be missing, namely to avoid â€œinvalidâ€ numbers (statistics). IIRC, putting analytics scripts at the end â€œensuresâ€ that the page is really loaded and that it can be considered a valid page view (otherwise, users cancelling or going back could be counted w/o actually seeing the entire document).
Why, just put all your scripts at the bottom, but have a big, opaque < div > covering the entire page with a "loading" gif in it. Then, when your initial scripts are done, fade it out and show the HTML content.
I've found this works particularly well for web applications, since users are most likely already used to having a loading screen while waiting for an application to load. You can even get fancy and update the loading"screen with relevant information, like a progress bar.
@Andrea – I specifically apply the onclick (nasty, but only used in desperate situations) on the links that should hook JS actions that I knew were required. i.e. there were only a couple of links that absolutely had to have the event handler.
Head, definitely. I want to apply JS behaviour as soon as possible to avoid confusing users with different behaviour when the page is not fully loaded so I use inline functioncalls right after the sections the behaviour should be applied to. Some people might call that a sin in itself but obviously they have never created a large website themselves…
Splitting up the JS functions into a file that is necessary beforehand and one that can be loaded afterwards only results in an extra HTTP request on first hit so is also less than optimal.
As for JS optimization: we use HTTP compression and are considering minification although that will only squeeze an insignificant extra bytes out of the size on the wire. Using f.i. Dean's packer is far less optimal and requires the client to 'unpack' the contents on every pageview which is actually more of a performance drain than a gain.
Thanks for great comments! Apparently there are many aspects to this, and no one-solution-fits-all is out there. And for high-performance web sites, NICCAI and Remy, with the <code>earlyClickHandler</code> solution, pose interesting ideas which aren't best practice, but rather about actually making things work the best way they can in real life.
I'm glad you liked the references in the post… 🙂
I haven't read all the other comments, so I might be repeating some things that other said.
I've looked at many of the videos from Yahoo Developer's area. And they contridict themselves somewhat. But one should not blindly go with one side or the other, just use common sense is my advice.
In the next video another guy said that you should put everything in one large file, causing less HTTP-requests.
Personally, I use both, depending on situation and where it's logical to have bigger or smaller files.
To stay on topic I usually put most scripts in the head, but when I can put them in the bottom of document – I do it. Specially if you use Google Analytics and similar on your site/app, they can make pages halt for several seconds.
One other thing; if you have scripts in smaller parts and you have a start page (after user logs in), then you can preload scripts by putting them in the bottom of the document.
Or you could just test it out yourself, with your favourite browsers at:
My new favourite tool 😀
I personally put scripts in the head section as for specs but the comments above depict other situation for preferring this.
Anyway the best pratice for the "clicked to early" problem is to use event delegation, this allows avoiding to wait for an "onload" event so the event can be added as soon as
the script starts (dynamically bound to new elements as they enter the DOM).
As a last resort if I have to wait for the entire HTML to be completely loaded I use my "ContentLoaded.js" to correctly handle the missing method for IE. The "doScroll('left')" trick for IE is great for these situations.
There may be scripts that can be loaded later through asynchronous "lazy loading" if the complete framework is too big. This may also be a reason to load all the pieces at the time they are needed. However a core script is necessary in the head to allow for "early page enlivenment" and to let the users click on buttons as soon as they see them appear.
Robert you may have a look at my lab site for "Event Delegates" you may be tempted to add something like that to your powerful DomAssistant, sources are on Google Code.
I wouldn't look to Yahoo for best practices on page loads – they've got the slowest pages on the net!
In spite of the great deal of attention they have paid to optimizing HTML and JS and PHP, they are at the mercy of bloated Flash files and no amount of code text optimization can possibly counteract that, which Yahoo has all but admitted.
Yes, statistics scripts should always be at the bottom, no matter what.
Thanks for the tip! Interesting tool!
So, I'm just not sure it's the best solution either. It's tough shit finding a good solution here. 🙂
When it comes to event delegation (and your IEContentLoaded solution and <code>doScroll</code>, which is funky stuff 🙂 ), I know you have good code and ideas. I guess it all depends on what level you want to take event delegation too, but in general I do propose to people to have an event on the containing element, and then work with what element was the actual target.
I like the js at the bottom of the document. I don't know if this is kosher, but it works even if you put if OUTSIDE of the closing
If you are looking for a definitive answer in which is better then you would be mistaken by doing so.
In the header initialize variables and functions that are essential for initial layout,
and only the â€˜basicâ€™ page functionality for your application. There are dom-ready scripts that work.
The problem is that so many are trying to use these giant JS libraries.
to add to that. I know what someone is going to say already. the dom will not be ready until the body loads –
instead of a complete dom-ready – use a targeted tag id or on load function not on the body can be an image or whatever to call the function.
also note that you can have JS includes anywhere in the document apply them as needed.
note: The header JS will only be slower on initial page load after it's been cached, it's faster to have it in the header. So it would be ideal to have 'some' script in the header section.
as always with these type of 'what is better answers' – it depends on the app/ page itself.
exacly how flash AS has been optimized. with AS3 you can now only import classes that are needed. the same principle sould be used with larger JS libraries.
I actually use both methods as needed. In general, my JS goes up top and is always optimized (consolidating multiple JS files into one — I do the same thing with CSS files too). That way, if I need inline stuff as the page loads it is available. If I need to then trigger something after the page is loaded, I hook to the onload event.
Finally, if I want to render something before the page finishes loading, like a marquee or news scroller, I put the code either at the end or just below the DOM elements that it requires. Provides a great performance balance!
http://www.radwebtech.com, http://www.scrapplet.com, http://www.xwinlib.com, http://www.dataportability.org
It’s a good question, but unfortunately there’s no good solution to it right now.
I always thought it looked tidier at the top with all my .css references, although never thought about performance issues. Nice post.