Scripts in Head or at end of Document? Pros / Cons

If it’s not necessary to make any changes to get the same behavior, then it really is that much work – when the benefit is 0, divide anything by it and you get the same infinite waste of time. It was just a question with a non-obvious (to me) answer – whether ready() is really an event handler and whether that ‘event’ fires if a script loads after the entire document is downloaded and, potentially, the document object has already been fully constructed.

Since jQuery’s ready() will run even if that code appears after the DOM is ready (according to Raffles’ demo), it’s not acting much like an event handler, and more like a procedure – check if the DOM is ready right now (don’t wait for an event to notify me of it), and if not, check again until it is. But I’ve never looked into how ready() is implemented to know that.

The implementation differs depending on the capabilities of the web browser, which is what makes it so very useful.

These days there is a shorter DOM ready method, and that is the jQuery callback


$(function() {
    // Document is ready
});

My (beginners) books also said to put JS in the <head>… they usually say this after pounding on the importance of separation of content and behaviour. Maybe because some of us are CSS people, we see <scripts> in the <body> similar to <style> tags in the head (instead of external). This is the reason why I haven’t been putting scripts in my <body>. It feels dirty when you’ve had the last 3-4 years of being told only HTML in the HTML, only CSS in the CSS…

If I have multiple pages running the same script, it doesn’t make sense to put it in the HTML to me then either… don’t I want caching? Analytics are meant to be per-page (and I’m allergic to them anyway) so they make sense to sit in the <body> I suppose.

Another reason: if for whatever reason I needed my page section 508 compliant (hopefully never), it requires a noscript tag for every script tag that sits in the body. Since many situations of good, unobtrusive JS don’t need (and shouldn’t have) a noscript tag, I can imagine going through flaming hoops even, just to keep the scripts referenced in the <head>.

When I’m building and testing, I always have the scripts in the body, but I’ll also have <style> tags too, simply because when starting something out, One Document to Rule Them All.

Chris Heilmann is someone I’m more than willing to listen to, though, so he could well convince me to start throwing more stuff into the HTML… the performance issues mentioned, to me that would depend on how many pages are running it (again, isn’t caching an issue? or not?) and I wonder if it doesn’t just make sense to have some slower load event handler if I’m also calling some lib every time as well?

ralph: did you read the article Paul listed re 7 sins of JS? In that article there are links to other articles by Heilmann too including an AJAX one that was interesting to read even if you do absolutely nothing with AJAX.
*edit http://www.sitepoint.com/forums/showthread.php?t=662004

No-one is advocating the use of JavaScript code within the HTML document! We’re still talking external JavaScript files here. The only issue is whether to link to it from the head (and having to use various event handlers) or to link to it from just before the </body> tag.

So a better comparison would be whether to use a <style> tag with an internal style sheet or to use a <link> tag referring to an external style sheet.

So a better comparison would be whether to use a <style> tag with an internal style sheet or to use a <link> tag referring to an external style sheet.

That is what I mean. I didn’t mean <style> tags in the body (!) nor inline CSS (that would be like <a onclick=“javascript: void”>hahaha</a>).

So I also don’t necessarily mean
<script type="text/javascript>
a bunch of JS…
</script>

but if every page is calling the same script at the bottom of the body:
<script src=“foo.js” type=“text/javascript”></script>

Actually I have a page where I took a script from someone, which sits externally, but didn’t have an event loader, and this was for a dropdown menu on every single page… and I ended up having
<script type=“text/javascript”>dropdown(‘menu’, ‘hover’, 300);</script>
on every page…
Even if there was a CMS so I wasn’t manually writing that every page, I still feel like I’d rather have that tucked away somewhere else too (but this would require a loader and if I understand this thread correctly, that’s a rather large penalty?).

Why would this constitute less separation between content and behaviour than if you had the exact same line just before </head>? :confused:

That’s bad, because then you’re not separating behaviour from content. You’d have to edit every page to make a change, whereas if you kept the script code externally, you’d only have one place to edit.

An onload event listener, or similar, isn’t a large penalty as such. You’ll need a code fork for IE vs everyone else, but that is taken care of if you use a JS library.

Rather, the penalty of having the script link in the head is that the download will stop altogether while the script is parsed. If the server is under heavy load, or if it’s a big script, there may be a noticeable delay in loading the page. If the script link is at the end of the document, there won’t be much of a noticeable delay. On the other hand, certain features that rely on the script may not work initially, even though the page seems to be fully loaded.

If you have such critical functions, you may be better off putting the script link in the head and use an event listener.

Why would this constitute less separation between content and behaviour than if you had the exact same line just before </head>?

Maybe it just seems that way to me because the <head> is where you reference stuff and the body is where the content is? I dunno. Is it not comparable to <style> vs <link to stylesheet> because the <script> tag with a src atty is similar to an image called and thus is cached anyway?

That’s bad, because then you’re not separating behaviour from content. You’d have to edit every page to make a change, whereas if you kept the script code externally, you’d only have one place to edit.

Yes.

An onload event listener, or similar, isn’t a large penalty as such. You’ll need a code fork for IE vs everyone else, but that is taken care of if you use a JS library.

Good to hear it’s not so bad. No point in loading some huge library just for some sugar on a dropdown menu (and no other scripting), but yeah if I was using a lib I realise they all seem to have that pre-built.

If you have such critical functions, you may be better off putting the script link in the head and use an event listener.

Ok, I think someone else also mentioned this too.

Thanks for clarifying everything.

Just encountered a little bit of stumbling block with importing at the end of the body.

In my onload script the first action is to set a css classname for the page of JS. Meaning it will be styled for javascript. It just adds this to the wrapper.

If I do something like this


<script src="JS/DPS_onLoad.js" type="text/javascript"></script>
</body>

When you load the page there’s a split second, while it loads the onload.js script, where the page is displayed in a non javascript format.

The alternative, which works is taking that line out and making it inline like this.

<script type = "text/javascript">Anim8.iD("wrapper").newClass("JS");</script><!-- set stylesheet -->
<script src="JS/DPS_onLoad.js" type="text/javascript"></script>
</body>

The point I’m making is that you still have to account for the loading time of your script on top of the domready status.

RLM

So this concern has already been addressed. In this case it might be better to load the script early (in the head) and use an event handler. Especially if the script is as small as that, where the delay is negligible.

So this concern has already been addressed. In this case it might be better to load the script early (in the head) and use an event handler. Especially if the script is as small as that, where the delay is negligible.

Good advice and apologies for missing that.

At the very least I’ve supplied an example that illustrates your point.:slight_smile:

RLM

I flicked through the JavaScript Difinitive Guide today, and noted that the author (Flannagan) seems only very coyly to address where to place scripts in a document. I finally found a page discussing it, but it was hard to get a clear answer from it. He does speak several times of “gray areas”. (See p256 if you have edition 5.)

Here are just a few quotes I found interesting, albeit somewhat confusing, and which are probably horribly out of context (sorry!):

Most browsers seem to allow scripts to manipulate any document elements that appear before the <script> tag… However, no standard requires it to work…

The only consensus that exists in this gray area is that it is safe to manipulate the document once the onload event has been triggered…

One technique (whose safety is debated) is to place the manipulation code at the end of the document.

He also notes that event handlers might fail if triggered while the page is only partially loaded, and that “this is one reason to define all functions in scripts in the <head> of a document”, but that the scenario “is uncommon in practice, and it is not usually worth the extra coding effort required to aggressively protect against it”.

To be honest, I can’t get any kind of a straight answer from that.

I get the sense from this thread that it is essentially easier to place JS links at the end of a document and that there’s no really major downsides to doing so. I’m still wondering what happens with scripts that insert code into the DOM (like special classes and elements) but I guess the DOM is not the same as the downloaded code anyway. I’ll have to test that, if I can.

No, but thanks for pointing it out. I hadn’t seen it.

Yes, I was wondering that. I guess if the scripts are unobtrusive, the page will still be usable, but it might get a little confusing for users to encounter this.

In case it’s of interest, I was looking at a rather pretty site today that uses a lot of jQuery, and noticed that the code was all referenced at the end of the document:

http://www.grigorlawyers.com.au/

Does he mention anything about who is debating this? I’ve never heard of any problems in that area. Is it something that affects really old browsers only?

If Chris Heilmann recommends putting scripts just before </body> whenever possible, that’s good enough for me. :slight_smile:

Not to mention that Yahoo have been recommending this as a best practice for years, and Google are asking you to do the same too.

For the ultimate in safety you can keep the scripts in the head, and use the addEventListener or attachEvent methods. In most cases though it’s as effective to place the script just before the </body> tag, and easier to achieve.

He does speak several times of “gray areas”. (See p256 if you have edition 5.)

Good lord, I had some excellent Thai tea once and I kept the bag to retain the smell (at least until I can find that same tea to buy for myself!) and I had stuffed it into my Definitive Guide… guess which page it was on?!? Creepy.

Does he mention anything about who is debating this? I’ve never heard of any problems in that area. Is it something that affects really old browsers only?

No. The following sentences are:

An IE-specific technique is to put the document manipulation code in a <script> that has both defer and src attributes. A Firefox-specific technique is to make the document-manipulation code an event handler for the undocumented DOMContentLoaded event, which is fired when the document is parsed but before external objects, such as images, are fully loaded.

I think he may be doing some butt-covering… while he is regularly updating, if he doesn’t hear a consensus from JS guys “out there in the real world” then he’s not going to proscribe something that may end up breaking in some weird browser. Or he’s being careful because the specs aren’t specific.

Well, Chris works for Yahoo, so it’s not a big mystery. :slight_smile:

As poes said, no.

If Tommy Olsson recommends putting scripts just before </body> whenever possible, that’s good enough for me. :slight_smile:

That seems to sum up this whole thread perfectly.

And so does that.

With HTML as soon as an element is added to the DOM it can be referenced from the JavaScript. So for HTML the best place for JavaScript is just before the </body> tag where you know all the elements in the DOM have loaded and don’t need to test if they have.

With XHTML the DOM can’t be accessed from JavaScript until after it has completely leaded and so the JavaScript has to go inside the <head> with an appropriate listener for when the DOM has finished loading.

To get your scripts to load faster in both cases the only script referenced from within the HTML should be one to add the script tags into the page using JavaScript. That way all b rowsers can then load the scripts in parallel rather than one at a time as most do when the script is diurectly called from the (X)HTML.

Very interesting! When you say XHTML, do you mean real XHTML or also that which is served as HTML?

I don’t really understand your last comment:

Any chance of a brief example of what that means, as I’m not sure how to interpret that?

Somethin’ like

var el = document.createElement('script');
el.type = 'text/javascript';
el.src = 'http://www.w3counter.com/stats/pwidget.js';
document.body.appendChild(el);

I almost never see people do this, but it has its uses.

OK, thanks Dan. It sounded like something of this sort was being suggested, but as I’ve never seen that done, I though I’d ask, in case I was way off the mark. :slight_smile: