197

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

Simone
  • 1,981
  • 2
  • 12
  • 4

9 Answers9

231

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.

EDIT: Firefox does support the DEFER attribute since version 3.6.

Sources:

mplungjan
  • 169,008
  • 28
  • 173
  • 236
eozzy
  • 66,048
  • 104
  • 272
  • 428
  • 5
    I've seen some modern advice that states scripts should be placed at the top. Placing the scripts at the bottom allow the images and other content in the body of the page to be loaded in parallel, but effectively causes the scripts in the page to be loaded later - the entire HTML body needs to be downloaded before the browser knows about the script URLs to load. Most people reference the Yahoo guide, which is no longer accurate - Firefox does indeed honor deferred attributes on scripts. Deferral at the top is going to result in a faster page load if you measure it. – ShadowChaser Jun 23 '12 at 16:42
  • Can I see some stats on page load speeds with this method? – Gabriel Alack Sep 30 '14 at 19:20
  • 1
    Firefox does support the DEFER atttibute since version 3.6. Source: http://www.w3schools.com/tags/att_script_defer.asp – Nikita 웃 Nov 19 '15 at 08:29
  • 2
    Update: as of early/mid 2016, all modern browsers have increased the number of connections per hostname to at least 6. – Night Owl May 23 '16 at 21:03
196

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.


Further caveats

There are some libraries that must be loaded before the DOM or CSS, such as polyfills. Modernizr is one such library that must be placed in the head tag.

Community
  • 1
  • 1
Chad Levy
  • 10,032
  • 7
  • 41
  • 69
  • 5
    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. – Chad Levy Jan 20 '10 at 23:11
  • 5
    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 Jan 20 '10 at 23:51
  • 9
    ChadLevy is right: there are some conditions under which jQuery plugins work better if they're referenced in the ``. 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 Jan 21 '10 at 00:34
  • 2
    @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. – Chad Levy Jan 21 '10 at 01:32
  • 1
    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 Jan 21 '10 at 03:25
  • 2
    @Stefan: If your jQuery plugins are not allowed to manipulate the DOM, then what's the point? – Robert Harvey Jan 21 '10 at 03:31
  • @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 Jan 21 '10 at 06:29
  • @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 Jan 21 '10 at 06:36
  • 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 `.` If the script is put in the ``, the jQuery gets a chance to apply its changes before the customer sees the page, or any part of it. That simple. – Robert Harvey Jan 21 '10 at 15:08
  • @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 Jan 21 '10 at 15:26
  • @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 Jan 21 '10 at 20:47
  • 1
    @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 Jan 21 '10 at 22:34
  • 1
    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 Jan 21 '10 at 22:38
  • 1
    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 Jan 21 '10 at 22:41
  • 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. – Chad Levy Jan 21 '10 at 23:42
  • @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 Jan 22 '10 at 02:14
  • 1
    @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 `` tag). – Robert Harvey Jan 22 '10 at 02:18
  • 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 ``, but this question got me thinking a little more about the reasons why. – Robert Harvey Jan 22 '10 at 02:33
  • This was an awesome dialogue. I learned a crap load. Good job guys. – Padawan Nov 19 '15 at 17:25
  • regarding Modernizr I would like to add a link to a comment from Paul Irish about considering not placing it in the head. https://github.com/Modernizr/Modernizr/issues/878#issuecomment-41448059 – hans2103 May 04 '16 at 07:42
38

Only load jQuery itself in the head, via CDN of course.

Why? In some scenarios you might include a partial template (e.g. ajax login form snippet) with embedded jQuery dependent code; if jQuery is loaded at page bottom, you get a "$ is not defined" error, nice.

There are ways to workaround this of course (such as not embedding any JS and appending to a load-at-bottom js bundle), but why lose the freedom of lazily loaded js, of being able to place jQuery dependent code anywhere you please? Javascript engine doesn't care where the code lives in the DOM so long as dependencies (like jQuery being loaded) are satisfied.

For your common/shared js files, yes, place them before </body>, but for the exceptions, where it really just makes sense application maintenance-wise to stick a jQuery dependent snippet or file reference right there at that point in the html, do so.

There is no performance hit loading jquery in the head; what browser on the planet does not already have jQuery CDN file in cache?

Much ado about nothing, stick jQuery in the head and let your js freedom reign.

virtualeyes
  • 11,147
  • 6
  • 56
  • 91
  • 1
    many, many browsers do not; about 2% is the highest figure I've read, when you take the version into account and the fact caching is based on exact resource names, so jquery1.4.2 is not the same as jquery1.7, or 1.9.1 or ... – Toni Leigh Sep 20 '13 at 08:26
  • Of those `2%`, say, half will leave before the page loads for the first time. This way you are losing `1%` of the visitors, but potentially saving yourself a lot of development time and trouble. See if this makes sense with your business model... – Sergey Orshanskiy Apr 23 '14 at 20:45
13

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.

EMP
  • 59,148
  • 53
  • 164
  • 220
  • 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 Jan 21 '10 at 03:38
  • 6
    Oh well, can't win them all! I'm of the belief that I understand its implications. :) – EMP Jan 21 '10 at 03:45
  • 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 Jan 21 '10 at 06:49
  • 4
    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 Jan 21 '10 at 06:54
  • @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 Jan 21 '10 at 15:10
6

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
  • 66,414
  • 68
  • 253
  • 406
5

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
  • 178,213
  • 47
  • 333
  • 501
  • 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 Jan 20 '10 at 23:54
  • 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 Jan 21 '10 at 03:15
  • 2
    @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 Jan 21 '10 at 03:41
  • yes, it will, trust me. however, you'd have to modify your markup and likely the Treeview plugin. – Dan Beam Jan 21 '10 at 03:55
  • 2
    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 Jan 21 '10 at 04:22
  • I've found that with Kendo, I must put the scripts at the top of the page. The controls just won't work without scripts at the top – Robert Achmann Nov 03 '14 at 19:06
  • 1
    Cheers Robert, I am also using ASP.NETMVC with forms in partials. It makes sense to keep the javascript within the partial as the new fields are re-assigned their functionality each time the partial is executed (say for validation). I have only faced issues with this when attempting to use `@Html.Action`, which dynamically writes a result to the output, as my partial gives `$ is undefined` meaning I instead have to use .load('@Url.Action') to load the partial. But this gives a fouc due to the extra request. Based on your input, I shall just move jquery above the RenderBody() in my master page – Malkin Feb 17 '15 at 16:33
4

Although almost all web sites still place Jquery and other javascript on header :D , even check stackoverflow.com .

I also suggest you to put on before end tag of body. You can check loading time after placing on either places. Script tag will pause your webpage to load further.

and after placing javascript on footer, you may get unusual looks of your webpage until it loads javascript, so place css on your header section.

Mujah Maskey
  • 8,654
  • 8
  • 40
  • 61
  • 2
    But, you could achieve the same thing using defer on the script. http://www.w3schools.com/tags/att_script_defer.asp – Jack Jan 03 '14 at 17:20
1

Just before </body> is the best place according to Yahoo Developer Network's Best Practices for Speeding Up Your Web Site this link, it makes sense.

The best thing to do is to test by yourself.

G_real
  • 1,137
  • 1
  • 18
  • 28
Soufiane Hassou
  • 17,257
  • 2
  • 39
  • 75
1

For me jQuery is a little bit special. Maybe an exception to the norm. There are so many other scripts that rely on it, so its quite important that it loads early so the other scripts that come later will work as intended. As someone else pointed out even this page loads jQuery in the head section.