What's Pros and Cons: Putting JavaScript in Head and Putting Just Before the Body Close

What's Pros and Cons: putting javascript in head and putting just before the body close

From Yahoo's Best Practices for Speeding Up Your Web Site:

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.

In some situations it's not easy to
move scripts to the bottom. If, for
example, the script uses
document.write to insert part of the
page's content, it can't be moved
lower in the page. There might also be
scoping issues. In many cases, there
are ways to workaround these
situations.

An alternative suggestion that often
comes up is to use deferred scripts.
The DEFER attribute indicates that the
script does not contain
document.write, and is a clue to
browsers that they can continue
rendering. Unfortunately, Firefox
doesn't support the DEFER attribute.
In Internet Explorer, the script may
be deferred, but not as much as
desired. If a script can be deferred,
it can also be moved to the bottom of
the page. That will make your web
pages load faster.

Therefore, in general, it is preferrable to put them at the bottom. However, it isn't always possible, and it often doesn't make that much of a difference anyway.

What are the pros and cons of including Javascript right before the /head tag vs the /body tag?

The advice about <head> is to not LINK TO EXTERNAL scripts that need to be downloaded. This blocks parallel downloads. Google's newest tracking code uses lazy loading, and doesn't block parallel downloads.

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();

Is putting the javascript before the closing body tag okay on an asp.net website?

"Is putting the javascript before the closing body tag okay on an asp.net website?"

Short answer. Yes.

Long answer. It depends upon the javascript.

Some things might not work so well after page load because, as written, they just need to load certain resources in DOMReady or before, and the subsequent logic might count on that. That is, if you have any jQuery that adds images on DOMReady, and then need to process those images, get their heights or whatever, you might have a bit of code that runs when the page is loaded (after the images are loaded). If the page has already been loaded, this strategy doesn't work. onload doesn't fire twice, IIRC.

Did it have to be written that way? No, it might be better to write some code that only runs after each of the images (or whatever other resources) have been verified to have been loaded, which is generally easy enough if you have the right code snippets in mind, but it's not trivial, either.

"What am I doing wrong? And what could I do to load my .js files after page load?"

There's alotta ways things can be done "wrong", and I bet one could probably write a whole chapter of all kinds of checks and still not cover all cases. I'm not saying this to discourage you from attempting to rewrite so that they could be loaded after page load, because I think covering the common cases is easy enough--I just don't trust myself to accurately list the most common cases off the top of my head.

Should I write script in the body or the head of the html?

I would answer this with multiple options actually, the some of which actually render in the body.

  • Place library script such as the jQuery library in the head section.
  • Place normal script in the head unless it becomes a performance/page load issue.
  • Place script associated with includes, within and at the end of that include. One example of this is .ascx user controls in asp.net pages - place the script at the end of that markup.
  • Place script that impacts the render of the page at the end of the body (before the body closure).
  • do NOT place script in the markup such as <input onclick="myfunction()"/> - better to put it in event handlers in your script body instead.
  • If you cannot decide, put it in the head until you have a reason not to such as page blocking issues.

Footnote: "When you need it and not prior" applies to the last item when page blocking (perceptual loading speed). The user's perception is their reality—if it is perceived to load faster, it does load faster (even though stuff might still be occurring in code).

EDIT: references:

  • asp.net discussion: http://west-wind.com/weblog/posts/154797.aspx
    and here: http://msdn.microsoft.com/en-us/library/3hc29e2a.aspx
  • jQuery document ready discussion: http://encosia.com/2010/08/18/dont-let-jquerys-document-ready-slow-you-down/?utm_source=feedburner&utm_medium=email&utm_campaign=Feed%3A+Encosia+%28Encosia%29
  • the other answers on this question present valid information as well.
  • use www.google.com and www.bing.com to search for related information (there are a lot of references)

Side note: IF you place script blocks within markup, it may effect layout in certain browsers by taking up space (ie7 and opera 9.2 are known to have this issue) so place them in a hidden div (use a css class like: .hide { display: none; visibility: hidden; } on the div)

Standards: Note that the standards allow placement of the script blocks virtually anywhere if that is in question: http://www.w3.org/TR/1999/REC-html401-19991224/sgml/dtd.html and http://www.w3.org/TR/xhtml11/xhtml11_dtd.html

EDIT2: Note that whenever possible (always?) you should put the actual Javascript in external files and reference those - this does not change the pertinent sequence validity.

What are the disadvantages/problems of including scripts in the body of page rather than in the head element?

Read this:

http://groups.google.com/group/closure-library-discuss/browse_thread/thread/1beecbb5d6afcb41?hl=en&pli=1

The short story is that we don't want
to wait for DOMContentReady (or worse
the load event) since it leads to bad
user experience. The UI is not
responsive until all the DOM has been
loaded from the network. So the
preferred way is to use inline scripts
as soon as possible.

<div id="my-widget"></div>  
<script>
initWidget(document.getElementById('my-widget'));
</script>

Yes, it not as easy to
maintain but it leads to a better user
experience. By intentionally leaving
out DOMContentReady wrappers we have
been able to prevent Google Apps to
use on this anti pattern.

And this:

Using DOMContentReady considered anti-pattern by Google

External javascript calls. Header or at the bottom of the page?

It's always better to put your javascript just before the closing </body> tag, because it will guarantee that your styles and html code will load before any scripts not causing any delay.

Otherwise, your heavy scripts will load first with blank screen, and only after they are loaded, your page will appear.

Respect your users and let them navigate your website as soon as possible.

What is the difference when including script tag in HTML's header or body

Most of the time you want to include scripts at the bottom of the body section. The basic reason is to ensure that the page (and consequently the DOM) has fully loaded before any javascript is executed upon it.

Additionally, since downloading scripts blocks the browser from downloading anything else at the same time, the page will appear to load faster if the page elements are loaded before the script. However, unless you are a huge website that gets lots of traffic like Yahoo or Google, you probably do not need to consider this.

Where should I declare JavaScript files used in my page? In head/head or near /body?

It will often be argued that for speed purposes you should put script tags right at the end of the document (before the closing body tag). While this will result in the fastest page load, it has some serious downsides.

Firstly, a common idiom with Webpage development is to have a header file, a footer file and your content in the middle. To keep unnecessary JavaScript code to a minimum, you'll often want to put code snippets in individual pages.

If you include jQuery, for example, at the end of the document, your jQuery code snippets (like document ready stuff) must happen after that. That can be awkward from a development point of view.

Secondly, in my experience, because the page load is faster, you can end up noticing certain effects being applied because the page has already loaded by the time they are applied.

For example, if you put a table in a document and right before the body close tag put:

$(function() {
$("tr:nth-child(odd)").addClass("odd");
});

with appropriate styling, that effect being applied will often be visible. Personally I think that makes for a bad user experience potentially. I think often you're better off having the page load slightly slower (by putting scripts at the top) if you don't get disconcerting visual effects.

I generally advocate effective caching strategies so you only have to download JavaScript files when they change, as in Supercharging JavaScript in PHP (but the principles apply to any language, not just PHP) and still putting scripts at the top. It's far more convenient.

What are the pros and cons of adding script and link elements using JavaScript?

The blocking nature of document.write

document.write will pause everything that the browser is working on the page (including parsing). It is highly recommended to avoid because of this blocking behavior. The browser has no way of knowing what you're going to shuff into the HTML text stream at that point, or whether the write will totally trash everything on the DOM tree, so it has to stop until you're finished.

Essentially, loading scrips this way will force the browser to stop parsing HTML. If your script is in-line, then the browser will also execute those scripts before it goes on. Therefore, as a side-note, it is always recommended that you defer loading scripts until after your page is parsed and you've shown a reasonable UI to the user.

If your scripts are loaded from separate files in the "src" attribute, then the scripts may not be consistently executed across all browsers.

Losing browser speed optimizations and predictability

This way, you lose a lot of the performance optimizations made by modern browsers. Also, when your scripts execute may be unpredictable.

For example, some browsers will execute the scripts right after you "write" them. In such cases, you lose parallel downloads of scripts (because the browser doesn't see the second script tag until it has downloaded and executed the first). You lose parallel downloads of scripts and stylesheets and other resources (many browsers can download resources, stylesheets and scripts all at the same time).

Some browsers defer the scripts until after the end to execute them.

The browser cannot continue to parse the HTML while document.write is going on and, in certain cases, when the scripts written are being executed due to the blocking behavior of document.write, so your page shows up much slower.

In other words, your site has just become as slow as it was loading on a decades-old browser with no optimizations.

Why would somebody do it like this?

The reason you may want to use something like this is usually for maintainability. For instance, you may have a huge site with thousands of pages, each loading the same set of scripts and stylesheets. However, when you add a script file, you don't want to edit thousands of HTML files to add the script tags. This is particularly troublesome when loading JavaScript libraries (e.g. Dojo or jQuery) -- you have to change each HTML page when you upgrade to the next version.

The problem is that JavaScript doesn't have an @include or @import statement for you to include other files.

Some solutions

The solution to this is probably not by injecting scripts via document.write, but by:

  1. Using @import directives in stylesheets
  2. Using a server scripting language (e.g. PHP) to manage your "master page" and to generate all other pages (however, if you can't use this and must maintain many HTML pages individually, this is not a solution)
  3. Avoid document.write, but load the JavaScript files via XHR, then eval() them -- this may have security concerns though
  4. Use a JavaScript Library (e.g. Dojo) that has module-loading features so that you can keep a master JS file which loads other files. You won't be able to avoid having to update the version numbers of the library file though...


Related Topics



Leave a reply



Submit