Where to include JavaScript files in a document

Today I thought we’d talk about how, or rather were in the document, to include JavaScript files.

Getting head

I assume that each and everyone of you were taught to include your JavaScript files within the head element, and up to now, as far as you know, it has worked just fine for you.

Example:

<head>
	<script type="text/javascript" src="js/DOMAssistant.js"></script>
</head>

Going down?

However, another alternative approach started figuring on the web where people included their JavaScript files just before the closing body tag instead.

Example:

	<script type="text/javascript" src="js/DOMAssistant.js"></script>
</body>
</html>

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.
  • A JavaScript script file has to be loaded completely before a web browser even begins on the next JavaScript file. The effect of this, if the JavaScript files are included at the top of the document, is that it will be a visual delay before the end user sees the actual page. This is completely avoided if you include the JavaScript files at the end of the document.

It is also a recommended by Yahoo’s Best Practices for Speeding Up Your Web Site: Put Scripts at the Bottom.

Not satisfied?

While including the JavaScript files at the bottom helps us around the problem of delaying the page rendering, thus giving the impression that each page in the web site loads faster, it does have a drawback.

If the page is visible to the end user, but the JavaScript files haven’t finished loading yet, no events have been applied to the elements yet (because everyone uses an unobtrusive approach, right?) and the user might start clicking around and not getting the expected results.

If you have proper fallbacks, e.g. a link element which gets content via AJAX if JavaScript is supported and the proper event has been applied, otherwise it’s a normal link leading to another page, then the problem isn’t that bad. Still somewhat annoying, though.

I’ve been swaying back and forth with my opinions about how to tackle this, and my conclusion is that every end user will be affected by page rendering delays, white pages etc, while only the fast clicking types will ever experience the fallback solution when content is visible but the JavaScript files haven’t been completely loaded.

Therefore, I’m including my JavaScript files at the bottom of a web page.

How do you do it? And, do you have any good suggestions for the problem described with the web page being visible but the JavaScript files not loaded?

Posted in Developing,JavaScript,Technology |

39 Comments

  • Jeff L says:

    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.

    <code>

    (function() {

    blah;

    })();

    </code>

  • George says:

    Yep after the Yahoo! performance team's research I go before the closing body tag.

  • Andy says:

    Already doing this, but thanks for posting!

    I'm sure there are others that can benefit from this information.

  • Neovov says:

    It seems that you're working on something that require great performance. Thanks for all these posts :] !

  • NICCAI says:

    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.

  • Paul Irish says:

    I applaud you, Robert, for consistently being the man to bring sexual innuendo to JavaScript.

    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?

  • Dave Child says:

    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.

  • 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.

    Surely that’s not completely true? Wasn’t the entire point of finding a cross-browser DOMContentLoaded simply 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.

  • Remy Sharp says:

    I've come across exactly this problem. I was part of a team that built a trading system driven by JavaScript. Since the pages were large, and often complicated, we needed to optimise as much as possible => so we put our scripts at the bottom.

    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:

    http://remysharp.com/2007/10/01/catch-click-event

    My approach is large solutions: foot. Quick small, low traffic solutions, where I like, particularly: head.

  • Andreas says:

    @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?

    <code>

    <script type="text/javascript">(function(){

    for(var

    a = document.getElementsByTagName("a"),

    l = a.length;

    l–;

    a[l].onclick = earlyClickHandler

    );

    })();</script>

    </code>

    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 :)

  • Mike says:

    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.

  • Andreas says:

    @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.

  • André L says:

    "Getting head"!!!! baaaaaahahahahahhahahaha LMFAO!!!!

    You, Rob, are definitely THE Rockstar!!! :D

  • Jens Meiert says:

    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).

  • mdmadph says:

    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.

  • Remy Sharp says:

    @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.

  • Tino Zijdel says:

    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.

  • Robert Nyman says:

    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.

    Alternative cases might be sufficiently efficient if you compress all your JavaScript files into one, compress them and gzip them, and then include them in the <code>head</code> part of the document.

    Paul, André,

    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 one video the guy said that splitting large Javascript-files into smaller logical parts. This would make the browsing experience better, because the user don't need to download a lot of code that is useless on the current page.

    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:

    http://stevesouders.com/cuzillion/

    My new favourite tool :D

  • Diego Perini says:

    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.

    Diego Perini

  • Outtanames999 says:

    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.

  • Robert Nyman says:

    Andreas,

    Yes, statistics scripts should always be at the bottom, no matter what.

    Morgan

    Thanks for the tip! Interesting tool!

    Diego,

    Event delegation can be a good solution, and is in general the way to work with events. However, just as you say, many times people use a JavaScript library to apply events, and then that library need to be included before the event is applied anyway (unless one uses separate code for applying just that specific event, but then in turn, you have multiple places and ways to handle events, which isn't good either).

    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.

    Outtanames999,

    To be honest, I don't really know about their Flash files, but when it comes to HTML, CSS and JavaScript, I personally think their research has lead to a lot of great advice and practices.

  • Tim says:

    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

  • Sam says:

    If you are looking for a definitive answer in which is better then you would be mistaken by doing so.

    The correct answer is to use JavaScript in the header and includes inside the document and sometimes both.

    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.

    These libraries for building RIAs are far from optimal and not nearly as modular as they should be. I would think best practice would be to include JS files as needed through out the document in the form of progressive loading and progressive execution. Only including the parts that are needed for the current loaded content, and interchanging loading XHTML and JavaScript only as it is needed.

  • Sam says:

    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.

  • Sam says:

    you can also use javascript to include other JS. with an if statment, and include by document.write concating the include w/two strings.

  • Sam says:

    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.

  • [...] Where to include JavaScript files in a document – Robert’s talk – Web development and Internet tre… Include that JavaScript in the bottom of the page. (tags: javascript webdevelopment performance) [...]

  • [...] code, and one JavaScript block located at the bottom of their HTML code (read more about why in Where to include JavaScript files in a document) and just have id and class attributes to connect that code [...]

  • 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!

    Steve Repetti
    http://www.radwebtech.com, http://www.scrapplet.com, http://www.xwinlib.com, http://www.dataportability.org

  • Techie web says:

    It ok with interncal javascript. but how can we put js coming from some banners or google Adsense without disturbing layout. If i need my banners/google adsense on top, and still want to upload that script at last?

  • Robert Nyman says:

    Techie web,

    It’s a good question, but unfortunately there’s no good solution to it right now.

  • Linn Hansson says:

    [...] En första inblick i Javascript Genom att läsa på Wikin om Javscript, så fick jag reda på att scriptet ska läggas precis före bodys sluttagg. Anledningen är att det har flera fördelar. Normalt sett måste scriptet (tex bilden) måste laddas upp till fullo innan browsern börja ladda nästa JS-fil. Det gör att det tar längre tid för användare att se sidan. Genom att lägga scriptet i botten av sidan undviker man detta. Smart! Fler fördelar finns att läsa om på länk Robert Nymans sida. [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>