151

I have seen both ways, both implementation work just the structures are a bit different. In your experience, which work better and why?

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
Khoi
  • 4,502
  • 6
  • 29
  • 31

5 Answers5

112

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:

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.

Ty Mick
  • 75
  • 1
  • 7
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
  • 2
    Do you have a source that have more information about this page blocking issue or how browser download resources? – Khoi Aug 20 '10 at 14:08
  • @Khoi - the page render blocking is a commonly documented issue. Editing the answer to provide some other references as it depends somewhat on the environment (platform and browser/version) – Mark Schultheiss Aug 20 '10 at 14:40
  • Best answer on this topic so far, helpful! +1. – aIKid Feb 25 '14 at 05:38
  • Regarding "do NOT place script in the markup such as ", rare cases you might have to. Such as in img tag: onerror – Andrew Mar 17 '16 at 13:33
  • 1
    @Andrew `$().on("error", function(){});` is one example or if you want to avoid multiple errors (on the backup image) try `$().one("error", function(){});` with the `one` function - jQuery specific but you can reverse the source if you want pure JavaScript – Mark Schultheiss Mar 17 '16 at 14:12
  • Great tip. No more inline `event-handler attributes` for me :) –  Feb 11 '18 at 22:49
  • About "Note that whenever possible (always?) you should put the actual Javascript in external files and reference those": it is not "always" possible, since the server-side processing language may be writing some parts of the JavaScript language when the page is built-up. A typical example is the "PHP2JS" variable declaration: `var myvar = ;` So simple when done in the hosting page, isn't it? – Fabien Haddadi Jun 19 '18 at 12:30
  • @FabienHaddadi - that is a totally separate issue of how to get values from the host to the client page which you illustrate one example of. – Mark Schultheiss Jun 19 '18 at 12:41
43

The problem with writing scripts at the head of a page is blocking. The browser must stop processing the page until the script is download, parsed and executed. The reason for this is pretty clear, these scripts might insert more into the page changing the result of the rendering, they also may remove things that dont need to be rendered, etc.

Some of the more modern browsers violate this rule by not blocking on the downloading the scripts (ie8 was the first) but overall the download isn't the majority of the time spent blocking.

Check out Even Faster Websites, I just finished reading it and it goes over all of the fast ways to get scripts onto a page, Including putting scripts at the bottom of the page to allow rendering to complete (better UX).

Ken Struys
  • 1,789
  • 1
  • 10
  • 17
  • 4
    Good answer, technically putting scripts in the header is clean, but from an end user point of view and SEO putting scripts right at the bottom of the document as the very last thing has many, many benefits. On some pages I've seen the apparent responsiveness of the page increase many fold just by moving the script to the bottom. Overall it may not fully load any faster, but to the end user as they see content it feels faster! – Paul Hadfield Aug 20 '10 at 13:48
  • This seem rather true, I have problem delay my script execution until all of my resources have been loaded. And I have seen page that have scripts loaded inside body, that load resources so effectively. Could you explain this more clearly? – Khoi Aug 20 '10 at 13:51
  • The specification says to block? Is that true? I believe they block for rendering reasons and not because any spec says to do so! – Rob Aug 20 '10 at 13:52
  • @Rob I remember the book saying something about it, let me read over the spec and make sure (ill make edits if needed). – Ken Struys Aug 20 '10 at 13:54
  • @Rob can't find the word blocking in the html spec, it does mention the stopping of rendering (and the explanation of the script inserting html) but doesn't specifically say blocking, ill make edits. – Ken Struys Aug 20 '10 at 14:02
  • @Khoi I don't really know what you mean by more clearly. Anything specific? What do you mean "all resources"? The script will executed in order as the pages loads, it doesn't wait unless you use callbacks triggerd by attributes like onload. – Ken Struys Aug 20 '10 at 14:09
  • actually I fully get your point just now. I mean like image files and sound files sometime doesn't load on time or doesn't load at all. And using events such as onload/onready doesn't help. I have seen pages with scripts mostly stay in the body, that doesn't employ any special method, but still load all of the page's resources perfectly on time. – Khoi Aug 20 '10 at 14:29
  • Are there any benchmarks comparing javascript in the `head` section verses just before the close `body` tag section? It has always felt like a bit of an old wife's tale. surely the browser has to download the whole html document before it can either parse the head or body? why would modern browsers process a page synchronously? i.e stop parsing the html just because it encounters some script. – gawpertron Nov 09 '12 at 11:37
  • gawpertron: The downloading is done asynchrnously in modern browsers starting with ie8 (according to even fast websites by steve souders). The requirement of executing before continuing parsing comes from the fact that scripts can dramatically change the structure of the dom. For example, they can use document.write and emit parts of a document immediately and you might even have scripts that are dependent on those side effects (see this example and imagine them being external scripts http://jsfiddle.net/struys/pZwQw/). – Ken Struys Nov 09 '12 at 21:23
11

W3Schools have a nice article on this subject.

Scripts in <head>

Scripts to be executed when they are called, or when an event is triggered, are placed in functions.

Put your functions in the head section, this way they are all in one place, and they do not interfere with page content.

Scripts in <body>

If you don't want your script to be placed inside a function, or if your script should write page content, it should be placed in the body section.

Vinz
  • 2,010
  • 1
  • 13
  • 16
4

Head, or before closure of body tag. When DOM loads JS is then executed, that is exactly what jQuery document.ready does.

Dejan Marjanović
  • 19,244
  • 7
  • 52
  • 66
1

I always put my scripts in the header. My reasons:

  1. I like to separate code and (static) text
  2. I usually load my script from external sources
  3. The same script is used from several pages, so it feels like an include file (which also goes in the header)
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820