SitePoint Sponsor

User Tag List

Page 1 of 5 12345 LastLast
Results 1 to 25 of 110
  1. #1
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,299
    Mentioned
    460 Post(s)
    Tagged
    8 Thread(s)

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

    I'm new to JavaScript, and my initial understanding is that it's better to link to external scripts in the head of the document rather than at the end of the document. There are hassles with <head> links, though, such as having to prevent the script running until the page is loaded.

    Often I see scripts linked near the end of the <body> section, which seems to have some advantages.

    Would anyone be interested in listing / discussing the pros and cons of both approaches? Is linking to scripts at the bottom of the <body> a bad thing? I'm interested in this not only from a convenience point of view but also from a best-practice angle.

    Interested in any replies or links to other discussions.

  2. #2
    Follow Me On Twitter: @djg gold trophysilver trophybronze trophy Dan Grossman's Avatar
    Join Date
    Aug 2000
    Location
    Philadephia, PA
    Posts
    20,580
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    I put locally hosted scripts in the head of the document, compressed when they're any significant size. Minimize the number of files when possible to reduce the number of requests the browser has to make to the server. My reasons for that are:

    1) It just seems more tidy to have all the scripts in one place
    2) I usually use a CMS or framework that handles putting the necessary scripts for a page in the head, pasting them into the body of individual pages makes it harder to keep track of them

    Externally hosted scripts usually go at the end of the document so that they don't prevent your page from loading if the external server is slow. This is common for things like web stats / counters and conversion tracking code.

  3. #3
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,299
    Mentioned
    460 Post(s)
    Tagged
    8 Thread(s)
    Thanks for the reply, Dan.

    In the CMSs I've used, it wouldn't be a problem to have the script links in an include which could be placed at the bottom of a template. But I guess it's a bit messier.

    I don't understand window.onload fully, but it seems a little strange to me that workarounds are needed if you want to have more than one function triggered on page load. That's partly why I've started to question links going in the head section. It seems window.onload can be dispensed with if the scripts are loaded last. Or is that a misconception?

    I'm starting to wonder if a decision should be made on a script by script basis. Some scripts need to be loaded before the page loads (like jQuery?), while others are better loaded after the page content.

    Looking forward to more opinions on this.

  4. #4
    SitePoint Author silver trophybronze trophy

    Join Date
    Nov 2004
    Location
    Ankh-Morpork
    Posts
    12,158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ralph.m View Post
    I'm new to JavaScript, and my initial understanding is that it's better to link to external scripts in the head of the document rather than at the end of the document.
    What gave you that idea? JavaScript gurus like Chris Heilmann are saying that putting script tags just before the </body> is optimal for performance, and it eschews the need for onload event handlers.

    The only reason to put scripts in the head these days is probably if you have a server-side app that generates bits of each page in different places (e.g., Java frameworks like JSF or Seam) and your templates are not constructed properly.
    Birnam wood is come to Dunsinane

  5. #5
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,299
    Mentioned
    460 Post(s)
    Tagged
    8 Thread(s)
    Quote Originally Posted by AutisticCuckoo View Post
    What gave you that idea?
    Heh heh, good question. I double-checked the books I have before starting this thread (such as Simply JavaScript), and they all direct you to place external links in the <head> section. I couldn't find a mention of placing them anywhere else, as if the idea is unthinkable. Yet I'm seeing the pre </body> more and more, and hence the question.

    JavaScript gurus like Chris Heilmann are saying that putting script tags just before the </body> is optimal for performance, and it eschews the need for onload event handlers.
    Interesting. I will look him up, because this is what I've been wondering. I wanted to hear a 'reputable' guru saying it. (Now I've heard two!)

    The only reason to put scripts in the head these days is probably if you have a server-side app that generates bits of each page in different places (e.g., Java frameworks like JSF or Seam) and your templates are not constructed properly.
    Very interesting. Thanks Tommy! This is very interesting.

  6. #6
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There's some scenarios well served by putting (some) javascript in the head, but generally, I put it all at the end of the doc.

  7. #7
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,299
    Mentioned
    460 Post(s)
    Tagged
    8 Thread(s)
    Quote Originally Posted by crmalibu View Post
    There's some scenarios well served by putting (some) javascript in the head
    Are you able to list any of those? I'd find it interesting to have a list for future reference. I was wondering about things like jQuery, but it might depend on what it's being asked to do, I suppose.

  8. #8
    Follow Me On Twitter: @djg gold trophysilver trophybronze trophy Dan Grossman's Avatar
    Join Date
    Aug 2000
    Location
    Philadephia, PA
    Posts
    20,580
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Here's an on-topic question for the JS gurus: If a script contains code that runs when the DOM is ready (e.g. jQuery's $(document).ready), and this script is included at the end of the document, might the DOM-ready trigger fire before the script has loaded, thus never running?

  9. #9
    Programming Team silver trophybronze trophy
    Mittineague's Avatar
    Join Date
    Jul 2005
    Location
    West Springfield, Massachusetts
    Posts
    17,227
    Mentioned
    194 Post(s)
    Tagged
    2 Thread(s)
    When I first started years ago I put my javascript all over the place, including lots of inline script. ... Progress due to maintenance nightmares. I started to reference external javacript files from script tags in the head. This was so functions would be available for the remaining inline function calls when the DOM loaded in. I have since removed inline function calls from my mark-up. But for the longest time it just didn't "feel right" referencing js files anywhere other than the head. I guess part of me felt it was taking a step backwards or something.

    Just as where my earlier inline function calls needed the script to already have been loaded, I eventually noticed that some scripts needed the DOM to be loaded (eg. getElementById('wrapper')) and I needed to use onload().

    Right now I do something like

    function doStuffA(){}
    function doStuffB(){}
    function doStuffC(){}
    function init(){
    doStuffA();
    doStuffB();
    doStuffC();
    }

    referenced in the head. And I have
    onload = init; and Google analytics before the closing body tag.

    I forget now and I imagine things have changed some, but I remember reading about there being browser differences in what sequence things loaded in. But I guess the main thing is to determine what needs what to be already loaded in when it's needed.

  10. #10
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ralph.m View Post
    Are you able to list any of those? I'd find it interesting to have a list for future reference.
    Sometimes you just don't want to wait for the entire page to load to add certain javascript behavior. Of course, adding too much js too early will slow the page down too. Having the ui drastically change when the page finishes loading when js kicks in to enhance it isn't ideal imo. A page can take a long time to load for some people on certain devices.

    You can usually get a good compromise by just getting the right styles loading early so the ui will be progressively rendering as the suitable js or non-js ui. But, sometimes things are more complicated and css and noscript solutions are messy.

    You might even find it nice to have a small javascript widget up and running asap as the page loads. For example, I personally like it when the js nav menu is usable right away before the rest of the page loads.

  11. #11
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dan Grossman View Post
    Here's an on-topic question for the JS gurus: If a script contains code that runs when the DOM is ready (e.g. jQuery's $(document).ready), and this script is included at the end of the document, might the DOM-ready trigger fire before the script has loaded, thus never running?
    If I understand you right, the event shouldn't trigger if the script was actually in the html. If you loaded it via other means, ya it could fire before your script gets executed.

    Regardless, your function will get called. It checks if the event already fired, and either queues your function up with any others that might have been queued, or just calls it.

  12. #12
    SitePoint Author silver trophybronze trophy

    Join Date
    Nov 2004
    Location
    Ankh-Morpork
    Posts
    12,158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dan Grossman View Post
    Here's an on-topic question for the JS gurus: If a script contains code that runs when the DOM is ready (e.g. jQuery's $(document).ready), and this script is included at the end of the document, might the DOM-ready trigger fire before the script has loaded, thus never running?
    I can't answer your question, but why would you want to do something that stupid? If the script is at the end of the document, you don't need the event handlers to start the script.

    But since the <script> tag is part of the DOM, my guess is that the DOM-ready even would occur after the the script has been loaded and executed.

    In my eyes it's a moot question, though, since there's no reason to use the event if the script is already after the content.
    Birnam wood is come to Dunsinane

  13. #13
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Here's an on-topic question for the JS gurus: If a script contains code that runs when the DOM is ready (e.g. jQuery's $(document).ready), and this script is included at the end of the document, might the DOM-ready trigger fire before the script has loaded, thus never running?
    While Tommy's comment is of course the voice of reason, I made a test case to see what happens:

    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
    <html>
    <head>
      <title>Testing ondomcontentloaded</title>
      <script type="text/javascript">
        function addP(txt) {
          var li = document.createElement('li');
          li.appendChild(document.createTextNode(txt));
          document.getElementById('stages').appendChild(li);
        }
        document.addEventListener('DOMContentLoaded', function() {
          addP('DOMContentLoaded from head');
        }, false);
        window.onload = function() {
          addP('window.onload');
        }
      </script>
    </head>
    <body onload="addP('body onload attribute')">
    <h1>when exactly does DOMContentLoaded fire?</h1>
    <ol id="stages">
    </ol>
    <script type="text/javascript">
    addP('before domcontentloaded trigger at body bottom');
    </script>
    <script type="text/javascript">
    document.addEventListener('DOMContentLoaded', function() {
      addP('DOMContentLoaded from body bottom');
    }, false);
    </script>
    <script type="text/javascript">
    addP('after domcontentloaded trigger at body bottom');
    </script>
    </body>
    <script type="text/javascript">
    document.addEventListener('DOMContentLoaded', function() {
      addP('DOMContentLoaded after closing body tag');
    }, false);
    </script>
    </html>
    <script type="text/javascript">
    document.addEventListener('DOMContentLoaded', function() {
      addP('DOMContentLoaded after closing html tag');
    }, false);
    </script>
    (yes, I know the last two <script>s are very wrong)

    Results:

    1. before domcontentloaded trigger at body bottom
    2. after domcontentloaded trigger at body bottom
    3. DOMContentLoaded from head
    4. DOMContentLoaded from body bottom
    5. DOMContentLoaded after closing body tag
    6. DOMContentLoaded after closing html tag
    7. body onload attribute


    It seems like DOMContentLoaded fires right after absolutely everything in the HTML source has been parsed, but before window.onload, which as Tommy said (regarding <script> being a part of the DOM) makes sense.

    Interestingly, having an onload="" attribute in the <body> overwrites window.onload in javascript (at least in FF3.6) - even if the attribute is empty or wrong. Hence why window.onload isn't part of the results. I wasn't expecting that to happen, but I suppose it makes sense.

    So anyway, DOMContentLoaded can be used anywhere, stupidly or otherwise.

  14. #14
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Hmmm very interesting question and answers! I've seen this a few times on some blogs as well about referencing external JS files at the bottom of the page (before the closing body tag) but I've always referenced external JS files in the head because that's what books encourage and it's what most people seem to do.

    I guess I'd like to add a question to this thread. Which way should you reference external JavaScript files? In the head of the document or at the bottom of the document before the closing body tag?

    If there isn't a defined way in which you should reference external JS files (and referencing them in the head is just the most popular way) then which would you recommend?

    Andrew Cooper

  15. #15
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Andrew, how are your questions any different to Ralph's original, and how are they not answered already?

  16. #16
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Raffles View Post
    Andrew, how are your questions any different to Ralph's original, and how are they not answered already?
    Ralph is asking for the advantages / disadvantages of these methods and views on them from other members. I'm asking for confirmation on which method should be used, as in the standard method? There are different methods for inserting markup / content into HTML documents from external JS files such as innerHTML and createElement() and createTextNode() and both methods are used widely but innerHTML isn't a standard, although most people would use innerHTML.

    I know most people reference external JS files in the head of the HTML document, but JS gurus reference it before the closing body tag but this may just be for performance increases, it may not be the standard way of referencing an external JS file. So yea, I'm asking for confirmation on which method should be used.

    And the second question is me asking what method should be used if neither of them are a set standard for referencing external JS files.

    Andrew Cooper

  17. #17
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,862
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Another consideration is that unlike other files where the browser can download between two and eight files at once, whenever the browser starts downloading a JavaScript file everything else stops until the browser finishes downloading that file.

    If you care going to place JavaScript of more than a half dozen lines of code in the head of the page then you should replace that code with JavaScript that adds the script tags to the head dynamically so that the JavaScripts are downloaded dynamically by JavaScript itself and not by the browser. That way they do not hold up the downloading of the other files AND multiple JavaScripts can download at the same time because the one file at a time limit only applies to JavaScript downloaded directly by the browser.

    You avoid that issue if you place the scripts at the end of the body.

    At the end of the body you no longer need to test for if the DOM has loaded if the page is HTML because any element in the HTML DOM can be accessed immediately that element has loaded without waiting for the rest of the page. It is only with XHTML that the entire DOM is inaccessible until everything has loaded.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  18. #18
    Follow Me On Twitter: @djg gold trophysilver trophybronze trophy Dan Grossman's Avatar
    Join Date
    Aug 2000
    Location
    Philadephia, PA
    Posts
    20,580
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AutisticCuckoo View Post
    I can't answer your question, but why would you want to do something that stupid? If the script is at the end of the document, you don't need the event handlers to start the script. But since the <script> tag is part of the DOM, my guess is that the DOM-ready even would occur after the the script has been loaded and executed.
    Is it really that stupid just to ask a question?

    1) Maybe I'd like to take some advice here and move scripts to the end of the document without rewriting them

    2) Just about every jQuery plugin on the web tells you to use document.ready, lots of people are just going to copy and paste that, I wanted to know if it'd still behave as usual as part of the <body>

    Quote Originally Posted by Raffles
    While Tommy's comment is of course the voice of reason, I made a test case to see what happens:
    Thanks, interesting

  19. #19
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    Another consideration is that unlike other files where the browser can download between two and eight files at once, whenever the browser starts downloading a JavaScript file everything else stops until the browser finishes downloading that file.
    This is starting to change in some of the very latest browsers
    http://www.stevesouders.com/blog/201...ading-roundup/

  20. #20
    SitePoint Author silver trophybronze trophy

    Join Date
    Nov 2004
    Location
    Ankh-Morpork
    Posts
    12,158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dan Grossman View Post
    Is it really that stupid just to ask a question?
    No, I didn't say you were stupid for asking the question. I only wondered why you'd want to do something as stupid as using an event handler for something that was already at the end of the document.

    Quote Originally Posted by Dan Grossman View Post
    1) Maybe I'd like to take some advice here and move scripts to the end of the document without rewriting them
    Is it really that much work to rewrite $(document).ready(myFunction); as myFunction();? You must lead a very stressful life, Dan!
    Birnam wood is come to Dunsinane

  21. #21
    Follow Me On Twitter: @djg gold trophysilver trophybronze trophy Dan Grossman's Avatar
    Join Date
    Aug 2000
    Location
    Philadephia, PA
    Posts
    20,580
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    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.

  22. #22
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Dan Grossman View Post
    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


    Code javascript:
    $(function() {
        // Document is ready
    });
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  23. #23
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,283
    Mentioned
    51 Post(s)
    Tagged
    2 Thread(s)
    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

  24. #24
    SitePoint Author silver trophybronze trophy

    Join Date
    Nov 2004
    Location
    Ankh-Morpork
    Posts
    12,158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    Maybe because some of us are CSS people, we see <scripts> in the <body> similar to <style> tags in the head (instead of external).
    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.
    Birnam wood is come to Dunsinane

  25. #25
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,283
    Mentioned
    51 Post(s)
    Tagged
    2 Thread(s)
    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?).


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •