Where should I put <script> tags in HTML markup?

Asked 2023-09-21 08:09:02 View 411,768

When embedding JavaScript in an HTML document, where is the proper place to put the <script> tags and included JavaScript? I seem to recall that you are not supposed to place these in the <head> section, but placing at the beginning of the <body> section is bad, too, since the JavaScript will have to be parsed before the page is rendered completely (or something like that). This seems to leave the end of the <body> section as a logical place for <script> tags.

So, where is the right place to put the <script> tags?

(This question references this question, in which it was suggested that JavaScript function calls should be moved from <a> tags to <script> tags. I'm specifically using jQuery, but more general answers are also appropriate.)

  • in case you're also just looking for a simple solution and you're using some server side generator like Jekyll, i recommend including the script with it instead. so much simpler! - anyone
  • If coming from a search engine looking for this: Many of the answers are not clear exactly where the 'script tag' should be at the end. If the 'script' tag is after '</body>', HTML validation will result in "Error: Stray start tag script" (check option "source" and click "check" to see the HTML source). It should be before '</body>'. (The result is similar if the 'script' tag is at the very end, after the </html> tag.) - anyone
  • This is also addressed in Is it wrong to place the <script> tag after the </body> tag?. - anyone
  • T.L.D.R. put it inside the <head> tag with defer attribute, or even better make your script type='module'. It is 2022 now. - anyone

Answers

Here's what happens when a browser loads a website with a <script> tag on it:

  1. Fetch the HTML page (e.g. index.html)
  2. Begin parsing the HTML
  3. The parser encounters a <script> tag referencing an external script file.
  4. The browser requests the script file. Meanwhile, the parser blocks and stops parsing the other HTML on your page.
  5. After some time the script is downloaded and subsequently executed.
  6. The parser continues parsing the rest of the HTML document.

Step #4 causes a bad user experience. Your website basically stops loading until you've downloaded all scripts. If there's one thing that users hate it's waiting for a website to load.

Why does this even happen?

Any script can insert its own HTML via document.write() or other DOM manipulations. This implies that the parser has to wait until the script has been downloaded and executed before it can safely parse the rest of the document. After all, the script could have inserted its own HTML in the document.

However, most JavaScript developers no longer manipulate the DOM while the document is loading. Instead, they wait until the document has been loaded before modifying it. For example:

<!-- index.html -->
<html>
    <head>
        <title>My Page</title>
        <script src="my-script.js"></script>
    </head>
    <body>
        <div id="user-greeting">Welcome back, user</div>
    </body>
</html>

JavaScript:

// my-script.js
document.addEventListener("DOMContentLoaded", function() {
    // this function runs when the DOM is ready, i.e. when the document has been parsed
    document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});

Because your browser does not know my-script.js isn't going to modify the document until it has been downloaded and executed, the parser stops parsing.

Antiquated recommendation

The old approach to solving this problem was to put <script> tags at the bottom of your <body>, because this ensures the parser isn't blocked until the very end.

This approach has its own problem: the browser cannot start downloading the scripts until the entire document is parsed. For larger websites with large scripts and stylesheets, being able to download the script as soon as possible is very important for performance. If your website doesn't load within 2 seconds, people will go to another website.

In an optimal solution, the browser would start downloading your scripts as soon as possible, while at the same time parsing the rest of your document.

The modern approach

Today, browsers support the async and defer attributes on scripts. These attributes tell the browser it's safe to continue parsing while the scripts are being downloaded.

async

<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>

Scripts with the async attribute are executed asynchronously. This means the script is executed as soon as it's downloaded, without blocking the browser in the meantime. This implies that it's possible that script 2 is downloaded and executed before script 1.

According to http://caniuse.com/#feat=script-async, 97.78% of all browsers support this.

defer

<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>

Scripts with the defer attribute are executed in order (i.e. first script 1, then script 2). This also does not block the browser.

Unlike async scripts, defer scripts are only executed after the entire document has been loaded.

(To learn more and see some really helpful visual representations of the differences between async, defer and normal scripts check the first two links at the references section of this answer)

Conclusion

The current state-of-the-art is to put scripts in the <head> tag and use the async or defer attributes. This allows your scripts to be downloaded ASAP without blocking your browser.

The good thing is that your website should still load correctly on the 2% of browsers that do not support these attributes while speeding up the other 98%.

References

Answered   2023-09-21 08:09:02

  • @Jori Common practice is to load your javascript asap (and non-blocking via async) and postpone any DOM manipulations until the "DOMContentLoaded" event is dispatched. - anyone
  • I'm not clear on what touches the DOM and what doesn't. Can you clarify? Is it safe to do an async load on something like jquery.js? - anyone
  • @Doug For example document.write operates on the dom. The question isn't if a script manipulates the dom, but when it does. As long as all dom manipulation happens after domready event has triggered, you're ok. jQuery is a library, and as such doesn't - or shouldn't - manipulate the dom by itself. - anyone
  • This answer is misleading. Modern browsers don't stop parsing when they reach a synchronous script tag that may affect the HTML, they just stop rendering/executing, and continue parsing optimistically to start downloading other resources that will probably be requested subsequently if no HTML is affected. - anyone
  • Why the async and defer attributes are not used nowhere? I mean, I viewed a lot of HTML sources from internet, and I don't see the async and defer attributes anywhere. ... ? - anyone

Just before the closing body tag, as stated on Put Scripts at the Bottom:

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.

Answered   2023-09-21 08:09:02

  • Agreed with the concept and its explanation. But what happens if the user starts playing with the page. Suppose I've an AJAX dropdown which will start loading after the page has appeared to the user but while it is loading, the user clicks it! And what if a 'really impatient' user submits the form? - anyone
  • @Hermant Old comment but you may do the trick disabling the fields by default then enabling them using JS when the DOM is fully loaded. That's what Facebook seems to be doing nowadays. - anyone
  • If this is best practice, why does stack overflow include all their script tags in <head>? :-P - anyone
  • In some cases, especially in ajax heavy sites, loading in head can actually result in faster load times. See: encosia.com/dont-let-jquerys-document-ready-slow-you-down (note that the "live()" function is deprecated in jquery, but the article still applies with the "on()" or "delegate" function). Loading in <head> may also be needed to guarantee correct behavior as pointed out by @Hermant. Finally, modernizr.com/docs recommends placing its scripts in the <head> for reasons explained on its site. - anyone
  • WARNING: No, this WAS a better practice. put it inside the <head> tag with defer attribute, or even better make your script type='module'. It is 2022 now. - anyone

Non-blocking script tags can be placed just about anywhere:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async script will be executed asynchronously as soon as it is available
  • defer script is executed when the document has finished parsing
  • async defer script falls back to the defer behavior if async is not supported

Such scripts will be executed asynchronously/after document ready, which means you cannot do this:

<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
  * might throw "jQuery is not defined" error
  * defer will not work either
-->

Or this:

<script src="document.write(something).js" async></script>
<!--
  * might issue "cannot write into document from an asynchronous script" warning
  * defer will not work either
-->

Or this:

<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
  * might throw "jQuery is not defined" error (no guarantee which script runs first)
  * defer will work in sane browsers
-->

Or this:

<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
  * might not locate #header (script could fire before parser looks at the next line)
  * defer will work in sane browsers
-->

Having said that, asynchronous scripts offer these advantages:

  • Parallel download of resources:
    Browser can download stylesheets, images and other scripts in parallel without waiting for a script to download and execute.
  • Source order independence:
    You can place the scripts inside head or body without worrying about blocking (useful if you are using a CMS). Execution order still matters though.

It is possible to circumvent the execution order issues by using external scripts that support callbacks. Many third party JavaScript APIs now support non-blocking execution. Here is an example of loading the Google Maps API asynchronously.

Answered   2023-09-21 08:09:02

  • This is the correct answer for today - using this approach means it's easier to keep your widgets self contained, no need to do fancy <head> include logic. - anyone
  • I'm confused why you can't use async or defer when including jQuery as you specify in your second block: <script src="jquery.js" async></script>. Are you able to explain why? I thought I need to have the async tag in for performance—per the accepted answer—so my page can load even while jQuery is still loading]. Thanks! - anyone
  • @elbow 99% of times <script src=jquery.js> is followed by $(function(){ ... }) blocks somewhere in the page. Asynchronous loading does not guarantee that jQuery will be loaded at the time browser tries to parse those blocks hence it will raise $ is not defined error (you may not get the error if jQuery was loaded from cache). I answered a question about loading jQuery asynchronously and preserve $(function(){ ... }). I'll see if I could find it, or you can look at this question: stackoverflow.com/q/14811471/87015 - anyone
  • @SalmanA Thank you! Yes, I fall in that 99%. I first need jquery lib to load, then my remaining .js scripts. When I declare async or defer on the jquery lib script tag, my .js scripts don't work. I thought $(function(){ ... })protected that—guess not. Current solution: I don't add defer or async on jquery lib script, but I do add async on my follow up .js scripts. Note: the reason I'm doing any of this is to make Google Page Speed happy. Thx again for the help! Any other advice is welcome. (Or a link to your previous answer). :) - anyone
  • @elbow See stackoverflow.com/a/21013975/87015, it will only give you an idea but not the complete solution. You could instead search for "jquery async loader libraries". - anyone

The standard advice, promoted by the Yahoo! Exceptional Performance team, is to put the <script> tags at the end of the document's <body> element so they don't block rendering of the page.

But there are some newer approaches that offer better performance, as described in this other answer of mine about the load time of the Google Analytics JavaScript file:

There are some great slides by Steve Souders (client-side performance expert) about:

  • Different techniques to load external JavaScript files in parallel
  • their effect on loading time and page rendering
  • what kind of "in progress" indicators the browser displays (e.g. 'loading' in the status bar, hourglass mouse cursor).

Answered   2023-09-21 08:09:02

The modern approach is using ES6 'module' type scripts.

<script type="module" src="..."></script>

By default, modules are loaded asynchronously and deferred. i.e. you can place them anywhere and they will load in parallel and execute when the page finishes loading.

Further reading:

Answered   2023-09-21 08:09:02

  • Just a note that this will not work if you're just trying stuff out on your local filesystem with no server. At lest on Chrome you get a cross-origin error trying to load the js from the HTML even though they both have the same origin, your filesystem. - anyone

If you are using jQuery then put the JavaScript code wherever you find it best and use $(document).ready() to ensure that things are loaded properly before executing any functions.

On a side note: I like all my script tags in the <head> section as that seems to be the cleanest place.

Answered   2023-09-21 08:09:02

  • Note that using $(document).ready() doesn’t mean you can put your JavaScript anywhere you like – you still have to put it after the <script src=".../jquery.min.js"> where you include jQuery, so that $ exists. - anyone
  • It is not optimal to put script tags in the <head> section - this will delay display of the visible part of the page until the scripts are loaded. - anyone
    <script src="myjs.js"></script>
</body>

The script tag should always be used before the body close or at the bottom in HTML file.

The Page will load with HTML and CSS and later JavaScript will load.

Check this if required:

http://stevesouders.com/hpws/rule-js-bottom.php

Answered   2023-09-21 08:09:02

  • This actually answered the question. I was wondering nearly all the examples posted never gave the proper visual context of "end of the page" - anyone
  • This answer is very misleading and most probably wrong. The articles in Google and in MDN suggests that synchronous JS (which is the case here) always blocks DOM construction and parsing which will result in delayed first-render. Therefore, you cannot see the content of the page until the JS file is fetched and finishes executing regardless of where you place your JS file in the HTML document as long as it is synchronous - anyone
  • It also references points made in 2009 and no longer relevant. - anyone
  • did you actually mean "otherwise you'll be able to see the content before loading the js file and that's bad?" - anyone
  • It is good practice not to put script tags at the end of the body or html code. Just like other declarative or meta information this should go in the head section reducing clutter of none content related information all over the place. Get used to using async or even better defer. Word Press can be a bit tricky, though. It puts the JavaScript in the wp_head but without the defer. stackoverflow.com/questions/18944027/… - anyone

The best place to put <script> tag is before closing </body> tag, so the downloading and executing it doesn't block the browser to parse the HTML in document,

Also loading the JavaScript files externally has its own advantages like it will be cached by browsers and can speed up page load times, it separates the HTML and JavaScript code and help to manage the code base better.

But modern browsers also support some other optimal ways, like async and defer to load external JavaScript files.

Async and Defer

Normally HTML page execution starts line by line. When an external JavaScript <script> element is encountered, HTML parsing is stopped until a JavaScript is download and ready for execution. This normal page execution can be changed using the defer and async attribute.

Defer

When a defer attribute is used, JavaScript is downloaded parallelly with HTML parsing, but it will be execute only after full HTML parsing is done.

<script src="/local-js-path/myScript.js" defer></script>

Async

When the async attribute is used, JavaScript is downloaded as soon as the script is encountered and after the download, it will be executed asynchronously (parallelly) along with HTML parsing.

<script src="/local-js-path/myScript.js" async></script>

When to use which attributes

  • If your script is independent of other scripts and is modular, use async.
  • If you are loading script1 and script2 with async, both will run parallelly along with HTML parsing, as soon as they are downloaded and available.
  • If your script depends on another script then use defer for both:
  • When script1 and script2 are loaded in that order with defer, then script1 is guaranteed to execute first,
  • Then script2 will execute after script1 is fully executed.
  • Must do this if script2 depends on script1.
  • If your script is small enough and is depended by another script of type async then use your script with no attributes and place it above all the async scripts.

Reference: External JavaScript JS File – Advantages, Disadvantages, Syntax, Attributes

Answered   2023-09-21 08:09:02

It turns out it can be everywhere.

You can defer the execution with something like jQuery so it doesn't matter where it's placed (except for a small performance hit during parsing).

Answered   2023-09-21 08:09:02

  • XHTML will validate with script tags in the body, both strict and transitional. Style tags however may only be in the head. - anyone
  • Re "it doesn't matter where it's placed": But not so the result is not well-formed HTML? - anyone
  • This answer is particularly un-useful because it does not answer the question of where I should put <script> tags whatsoever (on top of being wrong). - anyone
  • Fair enough. It's been 13 years since I was that naive. - anyone

The most conservative (and widely accepted) answer is "at the bottom just before the ending tag", because then the entire DOM will have been loaded before anything can start executing.

There are dissenters, for various reasons, starting with the available practice to intentionally begin execution with a page onload event.

Answered   2023-09-21 08:09:02

  • Re "at the bottom"": But before the ending body tag (</body>)? Can you make it clearer? (But without "Edit:", "Update:", or similar - the answer should appear as if it was written today). - anyone

It depends. If you are loading a script that's necessary to style your page / using actions in your page (like click of a button) then you better place it at the top. If your styling is 100% CSS and you have all fallback options for the button actions then you can place it at the bottom.

Or the best thing (if that's not a concern) is you can make a modal loading box, place your JavaScript code at the bottom of your page and make it disappear when the last line of your script gets loaded. This way you can avoid users using actions in your page before the scripts are loaded. And also avoid the improper styling.

Answered   2023-09-21 08:09:02

  • Re "place your JavaScript code at the bottom of your page": But before the ending body tag (</body>)? Can you make it clearer? (But without "Edit:", "Update:", or similar - the answer should appear as if it was written today). - anyone

Including scripts at the end is mainly used where the content/ styles of the web page is to be shown first.

Including the scripts in the head loads the scripts early and can be used before the loading of the whole web page.

If the scripts are entered at last the validation will happen only after the loading of the entire styles and design which is not appreciated for fast responsive websites.

Answered   2023-09-21 08:09:02

You can add JavaScript code in an HTML document by employing the dedicated HTML tag <script> that wraps around JavaScript code.

The <script> tag can be placed in the <head> section of your HTML, in the <body> section, or after the </body> close tag, depending on when you want the JavaScript to load.

Generally, JavaScript code can go inside of the document <head> section in order to keep them contained and out of the main content of your HTML document.

However, if your script needs to run at a certain point within a page’s layout — like when using document.write to generate content — you should put it at the point where it should be called, usually within the <body> section.

Answered   2023-09-21 08:09:02

Depending on the script and its usage the best possible (in terms of page load and rendering time) may be to not use a conventional <script>-tag per se, but to dynamically trigger the loading of the script asynchronously.

There are some different techniques, but the most straightforward is to use document.createElement("script") when the window.onload event is triggered. Then the script is loaded first when the page itself has rendered, thus not impacting the time the user has to wait for the page to appear.

This naturally requires that the script itself is not needed for the rendering of the page.

For more information, see the post Coupling async scripts by Steve Souders (creator of YSlow, but now at Google).

Answered   2023-09-21 08:09:02

Script blocks DOM load until it's loaded and executed.

If you place scripts at the end of <body>, all of the DOM has a chance to load and render (the page will "display" faster). <script> will have access to all of those DOM elements.

On the other hand, placing it after the <body> start or above will execute the script (where there still aren't any DOM elements).

You are including jQuery which means you can place it wherever you wish and use .ready().

Answered   2023-09-21 08:09:02

You can place most of <script> references at the end of <body>.

But if there are active components on your page which are using external scripts, then their dependency (.js files) should come before that (ideally in the head tag).

Answered   2023-09-21 08:09:02

The best place to write your JavaScript code is at the end of the document after or right before the </body> tag to load the document first and then execute the JavaScript code.

<script> ... your code here ... </script>
</body>

And if you write in jQuery, the following can be in the head document and it will execute after the document loads:

<script>
    $(document).ready(function(){
        // Your code here...
    });
</script>

Answered   2023-09-21 08:09:02

  • it throws SyntaxError - anyone
  • Your answer wasn't wrong but was in dire need of being updated. - anyone
  • It is not a good idea to put the scripts at the end of your body or html code. It is common practice to put this kind of meta information right where it belongs: in the head. - anyone
  • Re "at the end of the document after ... the </body> tag": No, no, no!. If the 'script' tag is after '</body>', HTML validation will result in "Error: Stray start tag script" (check option "source" and click "check" to see the HTML source). If it is before, it validates. - anyone
  • If you still care a lot about support and performance in Internet Explorer before version 10, it's best to always make your script tags the last tags of your HTML body. That way, you're certain that the rest of the DOM has been loaded and you won't block and rendering.

  • If you don't care too much any more about in Internet Explorer before version 10, you might want to put your scripts in the head of your document and use defer to ensure they only run after your DOM has been loaded (<script type="text/javascript" src="path/to/script1.js" defer></script>). If you still want your code to work in Internet Explorer before version 10, don't forget to wrap your code in a window.onload even, though!

Answered   2023-09-21 08:09:02

  • In the accepted answer, this is refered to as the “antiquated recommendation”. If you still mean it, you probably should produce some reference to back it. - anyone

I think it depends on the webpage execution.

If the page that you want to display can not displayed properly without loading JavaScript first then you should include the JavaScript file first.

But if you can display/render a webpage without initially download JavaScript file, then you should put JavaScript code at the bottom of the page. Because it will emulate a speedy page load, and from a user's point of view, it would seems like that the page is loading faster.

Answered   2023-09-21 08:09:02

Always, we have to put scripts before the closing body tag expect some specific scenario.

For Example :

`<html> <body> <script> document.getElementById("demo").innerHTML = "Hello JavaScript!"; </script> </body> </html>`

Answered   2023-09-21 08:09:02

Prefer to put it before the </body> closing tag.

Why? As per the official doc: https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics#a_hello_world!_example

Note: The reason the instructions (above) place the element near the bottom of the HTML file is that the browser reads code in the order it appears in the file.

If the JavaScript loads first and it is supposed to affect the HTML that hasn't loaded yet, there could be problems. Placing JavaScript near the bottom of an HTML page is one way to accommodate this dependency. To learn more about alternative approaches, see Script loading strategies.

Answered   2023-09-21 08:09:02