views:

997

answers:

6

Where is the best place to put Jquery code (or separate Jquery file)? Will pages load faster if I put it in the footer?

+5  A: 

Most jquery code executes on document ready, which doesn't happen until the end of the page anyway. Furthermore, page rendering can be delayed by javascript parsing/execution, so it's best practice to put all javascript at the bottom of the page.

Stefan Kendall
+1  A: 

Just before </body> is the best place according to this link, it makes sense.

The best thing to do is to test by yourself.

Soufiane Hassou
+22  A: 

Put Scripts at the Bottom

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.

Nimbuz
+1 for giving best answer and not getting accepted answer
bobwah
+1 I second that, this is the correct approach
Dominic Barnes
...in most cases.
Robert Harvey
A: 

Standard practice is to put all of your scripts at the bottom of the page, but I use ASP.NET MVC with a number of jQuery plugins, and I find that it all works better if I put my jQuery scripts in the <head> section of the master page.

In my case, there are artifacts that occur when the page is loaded, if the scripts are at the bottom of the page. I'm using the jQuery TreeView plugin, and if the scripts are not loaded at the beginning, the tree will render without the necessary CSS classes imposed on it by the plugin. So you get this funny-looking mess when the page first loads, followed by the proper rendering of the TreeView. Very bad looking. Putting the jQuery plugins in the <head> section of the master page eliminates this problem.

Robert Harvey
Intranets are not subject to the same conditions as the internet, so the load delay is probably less perceptible. It's still advisable to follow the rules, though.
Duncan
no, putting the CSS identifiers / styles in the markup (instead of waiting for jQuery to do it on DOM ready) solves the problem.
Dan Beam
@Dan Beam: The Treeview is populated from a database table, and the Treeview's styles are set by the Treeview plugin based on the table's content, so no, that won't work.
Robert Harvey
yes, it will, trust me. however, you'd have to modify your markup and likely the Treeview plugin.
Dan Beam
Why would I do that when I can just put the unmodified Treeview Plugin script at the top of the page, and it will work just fine? That doesn't make any sense, Dan.
Robert Harvey
+4  A: 

All scripts should be loaded last

In just about every case, it's best to place all your script references at the end of the page, just before </body>.

If you are unable to do so due to templating issues and whatnot, decorate your script tags with the defer attribute so that the browser knows to download your scripts after the HTML has been downloaded:

<script src="my.js" type="text/javascript" defer="defer"></script>

Edge cases

There are some edge cases, however, where you may experience page flickering or other artifacts during page load which can usually be solved by simply placing your jQuery script references in the <head> tag without the defer attribute. These cases include jQuery UI and other addons such as jCarousel or Treeview which modify the DOM as part of their functionality.

Paperjam
This is just wrong.
Stefan Kendall
Well, consider this: http://themeforest.net/item/portfolious-professional-business-template/full_screen_preview/47805. It's a site theme I recently purchased which features on its homepage the use of jQuery with jCarousel. When I moved the script blocks from the head to the end of the file I noticed the images used in the carousel would all be shown at once during page load, whereas when the script files were in the head the page would load more smoothly.
Paperjam
Use CSS to set the initial state of the content. CSS should go in the head. Breaking something to make something else work is not the solution.If a visitor has to wait for jQuery and all associated plugins to load before any content is rendered, she may not stay long enough to see the content.
Duncan
ChadLevy is right: there are some conditions under which jQuery plugins work better if they're referenced in the `<head>`. If your markup is dependent on the jQuery plugin sorting out the content for you, it makes no sense putting the plugin reference at the bottom of the page, as you are going to get funky markup in your web page until the plugins load. Rules are meant to be followed until they don't work anymore, at which point rules should be broken.
Robert Harvey
@Duncan: Ideally this would be the case where you can control all dependencies. The thing about jQuery (more specifically things like jQuery UI and other addons) is by design you can't have complete control over their functionality, so adding something like visibility attributes to a DOM element so that it loads more gracefully might not be possible if an addon that uses that element won't take into account said attribute. Sometimes it's better to defy a simple convention than try to get a dependency to work the way you want.
Paperjam
Restructuring your page entirely with jQuery is a terrible idea. JavaScript was not meant to build web pages...that's what HTML is for.
Stefan Kendall
@Stefan: If your jQuery plugins are not allowed to manipulate the DOM, then what's the point?
Robert Harvey
@ChadLevy: Agreed. There is ideally and there is reality. However the DOM may not be ready at that time and jQuery should not do anything until the callback is received - so it shouldn't really matter where in the document it is called anyway. I would be interested in knowing what it does that makes it order-dependent.
Duncan
@RobertHarvey: If the jQuery plugin is sorting the content, it still shouldn't manipulate the DOM until the DOM is ready. So either your page load is delayed until the content is sorted and then it is inserted when the DOM is loaded, or it is both sorted and inserted when the DOM is loaded. (Or it's a game of Russian roulette as a possibly non-existent DOM is being changed). So either way it's still being done at the end. It therefore shouldn't make a difference. The only case I can think of is if jQuery modifies the CSS as well, which was my original point about setting initial state in CSS.
Duncan
The problem is a simple one. If you want the jQuery to be loaded and available to manipulate the DOM from the outset, it needs to be in the `<head>.` If the script is put in the `<head>`, the jQuery gets a chance to apply its changes before the customer sees the page, or any part of it. That simple.
Robert Harvey
@Robert: Not if **any** of what you're doing relies on the DOM being ready, which it usually does. By working on the DOM while it's loading, you introduce a slew of timing issues that you'll never be able to reproduce, but every customer will probably see at least once.
Stefan Kendall
@Stefan: jQuery has `document.ready()` to mitigate those issues, which I *always* use. I'm not working on the DOM until it *is* ready.
Robert Harvey
@Duncan: Since `document.ready()` is being called in both cases, I assume that the DOM is always ready when the jQuery code executes. But putting the jQuery scripts at the top of the page apparently allows the jQuery plugins to have their say about the final state of the page *before it is actually displayed to the user,* whereas putting the scripts at the bottom allows a brief period of time to elapse where the content can be partially rendered to the user in an incomplete state, before the jQuery has an opportunity to perform its own modifications to the page.
Robert Harvey
In my particular use case, modifying the plugins and CSS so that it all gets rendered properly prior to jQuery performing its modifications to the page is just not feasible. It is tantamount to doing the work twice and, since the styles are dynamically determined from content in the database (necessitating the use of script anyway), it is tantamount to doing the *same thing.*
Robert Harvey
I hope I am making myself clear. A rule is a good rule as long as it works, but ceases to be a good rule when it no longer works in a particular situation. You can still follow the rule when it works, but don't follow everyone else off the cliff just because they said that a rule is a rule, and that the rule should be followed without question.
Robert Harvey
I reworded my answer to better convey the edge case issue (which is what I was talking about in the first place). Hopefully it is now worded to more peoples' liking.
Paperjam
@RobertHarvey: Since you use dom.ready() it should make no difference where jQuery is referenced. For it to make a difference to the page rendering, it must be playing with CSS. I understand your point of view and agree that rules should not be followed blindly (cargo cult programming). It is perfectly acceptable to break them if you understand why, which clearly you do. How are you getting the style from the database? AJAX calls? It seems to me there must be a server side script somewhere, and I think I would choose dynamically generated CSS it over feeding it to Javascript. But YMMV.
Duncan
@Duncan: The jQuery TreeView control allows you to specify whether a particular node in the tree is a file or a folder, and whether or not the folder is open or closed (this is what I am storing in the database) via CSS styles. In addition, the control has an option where it will look at the current URL, and match it to a node in the tree, and expand all of the branches up to that node. All of this works regardless of where you put the script tag for the control, but problems with flashing and bogus pre-rendering are eliminated if you give the script control early (i.e. in the `<head>` tag).
Robert Harvey
These CSS styles are injected server-side, so that part of it really shouldn't matter. But there are also other styles that the plugin uses to fixup its markup, and make sure that the tree renders properly. I had already made the decision to move the script into the `<head>`, but this question got me thinking a little more about the reasons why.
Robert Harvey
+2  A: 

Nimbuz provides a very good explanation of the issue involved, but I think the final answer depends on your page: what's more important for the user to have sooner - scripts or images?

There are some pages that don't make sense without the images, but only have minor, non-essential scripting. In that case it makes sense to put scripts at the bottom, so the user can see the images sooner and start making sense of the page. Other pages rely on scripting to work. In that case it's better to have a working page without images than a non-working page with images, so it makes sense to put scripts at the top.

Another thing to consider is that scripts are typically smaller than images. Of course, this is a generalisation and you have to see whether it applies to your page. If it does then that, to me, is an argument for putting them first as a rule of thumb (ie. unless there's a good reason to do otherwise), because they won't delay images as much as images would delay the scripts. Finally, it's just much easier to have script at the top, because you don't have to worry about whether they're loaded yet when you need to use them.

In summary, I tend to put scripts at the top by default and only consider whether it's worthwhile moving them to the bottom after the page is complete. It's an optimisation - and I don't want to do it prematurely.

Evgeny
You had me until you dragged out the premature optimization argument. That's just another rule that people dogmatically follow without fully understanding its implications.
Robert Harvey
Oh well, can't win them all! I'm of the belief that I understand its implications. :)
Evgeny
+1 anyway. At least you're still thinking.
Robert Harvey
I'm not sure you need to worry if your scripts have loaded. Rendering blocks until a script has loaded, which is what the bulk of this discussion is about. So as long as you don't call anything before you load it, you're fine. And besides, that's what callbacks are for and you shouldn't really be embedding much else in your page. As I understand it, images don't block (they load in parallel) and in fact the DOM can be ready and your scripts running before images are completely loaded. It doesn't make sense to put the scripts first just to avoid them being blocked.
Duncan
Given that the general consensus is to put scripts at the bottom, wouldn't it be better to do that by default, and only move them to the top if you experience problems? Seems strange to do things backwards. Sometimes it's better to do the optimal thing if there is no difference in expended effort :)
Duncan
@Duncan, Yes that was my approach. I put the plugins at the bottom, and when I had problems, I put them at the top, and that fixed the problems.
Robert Harvey