By mipadi


2009-01-12 18:15:54 8 Comments

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.)

20 comments

@Bart 2014-06-05 21:20:51

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 & 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 type="text/javascript" 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 & 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 & 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 type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" 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 to script 2 is downloaded & executed before script 1.

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

defer

<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" 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.

According to http://caniuse.com/#feat=script-defer, 94.59% of all browsers support this. 94.92% support it at least partially.

An important note on browser compatibility: in some circumstances IE <= 9 may execute deferred scripts out of order. If you need to support those browsers, please read this first!

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 20% of browsers that do not support these attributes while speeding up the other 80%.

@wayofthefuture 2014-06-25 18:00:00

Using this method, what would be the best way to run javascript after all js files are loaded? Currently, I am using the onload event inside the opening body tag.

@wayofthefuture 2014-06-25 18:16:29

Does anyone have any thoughts on this approach? feedthebot.com/pagespeed/defer-loading-javascript.html

@Jori 2014-06-27 17:24:08

I can't really imagine a lot of scenarios where DOM is not modified by JavaScript. Could anyone give a example of a script that would use async?

@Jori 2014-06-27 17:45:55

Also when function are referenced by normally loaded JavaScript, from an async loaded JavaScript file, then it must wait for it to download right? It seems it gives me a uncaught reference error.

@mcNux 2014-07-23 22:18:53

Note that IE<10 may interleave execution of scripts when using defer so still not a failsafe solution - caniuse.com/#search=defer (updated answer as I think this is important)

@mcNux 2014-07-23 22:37:55

My update was rejected which I think is a shame because the statement "the website should still load correctly on the 20% of browsers that do not support these attributes" is misleading. Maybe someone with more reputation will be able to update the answer?

@Bart 2014-07-24 12:09:19

@mcNux I've added a note.

@Bart 2014-07-24 12:09:40

@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.

@Afzaal Ahmad Zeeshan 2014-08-03 14:38:58

+1, just read the list of your hierarchy and upvoted it. Such a great answer!

@Casey Falk 2014-08-15 21:27:11

I'm surprised nobody cited Google's explanation... developers.google.com/speed/docs/insights/BlockingJS

@Koray Güclü 2014-08-25 22:23:03

Defer does not seem to solve this issue on some browsers see stevesouders.com/hpws/rule-js-bottom.php

@Doug 2014-09-06 23:11:21

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?

@Bart 2014-09-09 15:34:38

@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.

@Fabio Beltramini 2014-10-16 21:23:57

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.

@KNU 2014-10-30 07:24:14

may I've reference for "If your website doesn't load within 2 seconds, people will go to another website."

@Can 2015-04-27 09:00:46

I guess that especially when getting scripts from a different domain like a CDN or subdomain they should be fine in the <head> For me it feels better (I'm just using a subdomain), and the sticky header for example and other stuff works already while loading which doesn't feel slower. By the way, Facebook is loading tons of scripts from the <head> too ;-) Cheers

@ClearCrescendo 2015-05-06 17:11:05

I've tried to find a reference showing that if scripts in the head are async that the head is guaranteed to be ready (They have all loaded) before the body readyState becomes loaded. I can't find such a reference but based on waterfalls from Chrome, Firefox and IE11 in all cases tested the body becomes loaded after all async javascript has completed loading. So existing 'execute on dom ready' functionality appears safe. I just haven't found references that it always is.

@Matthew Cornell 2015-08-05 14:27:18

How do you handle the case where a web application framework has a 'main' file with a <head> that loads scripts useful to all 'child' templates (e.g., JQuery), but where individual files need template-specific javascript?

@john c. j. 2016-05-10 14:02:55

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. ... ?

@Sean 2016-05-28 01:11:23

How does dynamically building the script tag and appending it compare? e.g. { var se = document.createElement('script'); se.type = 'text/javascript'; se.src = "//code.com/myscript.js"; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(se, s); } Is this similar to using defer? Also, what if I add "se.async = true;" in there? I've noticed third-party providers take this approach.

@giorgim 2016-11-24 18:57:28

@Bart What if I put script in head - and it say registers handler for button click. Since the button is created in body, will I be able to register such a handler?

@cbuchert 2017-01-17 18:33:23

@Onato, do defer and async still help if you are using http2?

@JohnLBevan 2017-04-18 17:37:03

Great answer. Any such recommendations on the link element / for stylesheets? I found this codepen.io/tigt/post/async-css-without-javascript; but am surprised that the problem of loading external files would be addresses separately by file type/use, rather than once for all external content.

@myDoggyWritesCode 2017-07-16 15:29:40

Nice answer. Can I assume that putting a script with defer is better to put before external css style tag inside head to take most benefit otherwise if put before </body> browser won't be able to request my defer script until css file is fetched.. Am I right?

@Adam 2017-10-01 12:25:40

This post is now 3 years old. I guess browser support should be above 90% now?

@rpivovar 2018-01-04 17:32:56

awesome answer.

@gman 2018-01-15 02:15:41

this answer is also antiqated, it's considered a waste to use type attributes on script tags. They aren't needed and are just pedantic

@Mohamed Elshahawy 2018-04-22 22:50:54

Scripts can be placed in the , or in the section of an HTML page, or in both.

<head>
<script></script>
</head>
or here
<body>
<script></script>
</body>

but for best practise to ignore any error you must put between body tag because if any problem discover in javascript, html not be stop work but if you but between header tag if any problem discover that will stop your page work

Blockquote

@orip 2009-01-12 23:37:11

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

But there are some newer approaches that offer better performance, as described in this answer 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).

@Mr_Blue 2017-11-09 12:33:51

At The End of HTML Document

So that it will not effect the loading of the HTML document in the browser at the time of execution.

@Sanjeev S 2017-11-27 06:12:19

Including scripts at the end is mainly used where the content/ styles of the website 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 site.

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.

@nada diaa 2017-10-28 16:34:54

the best place to write your JavaScript code in the end of document code after tag to load the document then execute js code. and if u write JQuery code write

$(document).ready (function{

//your code here

});

@Tech AG 2017-01-27 15:51:22

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 head tag).

@Amit Mhaske 2016-12-01 07:09:57

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 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 an user's point of view it would seems like that page is loading faster.

@AmanKumar 2016-07-16 11:16:47

<script src="myjs.js"></script>
</body>

script tag should be use always before body close or Bottom in HTML file.

then you can see content of the page first before loading js file.

check this if require : http://stevesouders.com/hpws/rule-js-bottom.php

@Ken Ingram 2016-12-16 01:23:21

This actually answered the question. I was wondering nearly all the examples posted never gave the proper visual context of "end of the page"

@Lingaraju E V 2017-10-26 06:31:26

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

@toxaq 2017-10-30 01:37:26

It also references points made in 2009 and no longer relevant.

@user5803163 2016-01-20 19:50:08

  • If you still care a lot about support and performance in IE<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 anymore about IE<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 IE<10, don't forget to wrap your code in a window.onload even, though!

@dakab 2016-01-20 20:10:44

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.

@user5803163 2016-01-20 20:40:42

@dakab : Thanks for the comment. I modified my answer!

@Szymon Toda 2015-06-29 12:38:16

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

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

In other hand placing it after <body> start or above will execute script (where there's still no DOM elements).

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

@Salman A 2015-02-06 11:19:25

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.

@Daniel Sokolowski 2015-07-07 18:17:47

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.

@elbowlobstercowstand 2015-08-06 08:10:39

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!

@Salman A 2015-08-06 09:12:08

@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

@elbowlobstercowstand 2015-08-06 21:22:36

@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). :)

@Salman A 2015-08-07 05:40:49

@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".

@elbowlobstercowstand 2015-08-07 16:08:39

@SalmanA: Thanks! I'll give it a whirl.

@Andrew Hare 2009-01-12 18:18:14

If you are using JQuery then put the javascript 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.

@Dan Lugg 2013-01-20 17:43:55

in the head...er? <header>?

@Rory O'Kane 2013-07-10 15:42:25

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.

@CyberMonk 2013-10-14 00:33:40

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.

@ProfK 2017-03-29 13:59:59

No, @Dan, a header element is part of the the HTML document content, and should occur one or more times within the body element. The head` tag is for meta-data and non-content data for the document. It is, these days, with defer and async an ideal place for script tags. header elements should only contain information that describes the section of the document that follows it.

@kojow7 2017-05-11 16:51:48

@ProfK, Dan was referring to the original unedited question when he posted this over 4 years ago. As you can see, the question was edited a year later.

@Cammel 2009-01-12 18:18:25

Just before the closing body tag, as stated on

http://developer.yahoo.com/performance/rules.html#js_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.

@Hemant Tank 2012-01-03 14:29:26

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?

@novato 2012-11-11 06:20:57

@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.

@cypher 2013-01-08 04:19:19

Just tested this with chrome, to check if this is still the same. It Is. You can check the differences in page load time of your browsers here. stevesouders.com/cuzillion

@Philip 2013-04-20 05:04:54

If this is best practice, why does stack overflow include all their script tags in <head>? :-P

@NkS 2013-05-15 03:15:48

Can I add after the body closing tag or will it be cause any performance problem?

@Nathan 2013-06-07 15:54:49

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.

@Alvaro 2014-04-03 09:12:21

In your quote it doesn't say anything about the body tag. Couldn't they be placed outside the body tag?

@Juan Miguel 2013-12-27 03:52:28

You can place where you want the scripts and one is not better than another practice.

the situation is as follows:

The page load linearly, "top-down", so if you put the script in the head ensures that it starts to load before everything, now, if you put it inside the body mixed with the code can cause page loads a unsightly manner.

identify good practice does not depend on where.

to support you, I will mention the following:

you can place:

and the page will load linearly

page is loaded asynchronously with other content

the content of the page will load before and after completion of loading the scripts are loaded

good practice here would be, when will implement each?

I hope I've been helpful, anything just answer me this issue.

@ahmedmzl 2013-11-18 04:41:17

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 on the top. If your styling is 100% CSS and you have all fallback options for the button actions then you can place it in the bottom.

Or best thing (if that's not a concern) is you can make a modal loading box, place your javascript 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.

@zachdyer 2012-12-29 06:06:02

It makes more sense to me to include the script after the HTML. Because most of the time I need the Dom to load before I execute my script. I could put it in the head tag but I don't like all the Document loading listener overhead. I want my code to be short and sweet and easy to read.

I've heard old versions of safari was quarky when adding your script outside of the head tag but I say who cares. I don't know anybody using that old crap do you.

Good question by the way.

@stpe 2009-01-12 21:06:03

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 straight forward 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).

@Allain Lalonde 2009-01-12 18:22:53

XHTML Won't Validate if the script is anywhere other than within the head element. 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).

@I.devries 2009-01-12 18:43:32

XHTML will validate with script tags in the body, both strict and transitional. Style tags however may only be in the head.

@dkretz 2009-01-12 18:18:48

The conventional (and widely accepted) answer is "at the bottom", 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.

Related Questions

Sponsored Content

29 Answered Questions

11 Answered Questions

[SOLVED] Why don't self-closing script tags work?

36 Answered Questions

[SOLVED] HTML form readonly SELECT tag/input

  • 2008-12-15 15:59:09
  • Jrgns
  • 486209 View
  • 442 Score
  • 36 Answer
  • Tags:   javascript html

12 Answered Questions

[SOLVED] Should I put input tags inside a label tag?

  • 2009-04-21 18:52:05
  • lucian.jp
  • 198731 View
  • 472 Score
  • 12 Answer
  • Tags:   html html5 semantics

13 Answered Questions

[SOLVED] Is the recommendation to include CSS before JavaScript invalid?

15 Answered Questions

[SOLVED] When is a CDATA section necessary within a script tag?

20 Answered Questions

[SOLVED] How to store arbitrary data for some HTML tags

  • 2009-01-11 02:02:14
  • nickf
  • 186660 View
  • 310 Score
  • 20 Answer
  • Tags:   javascript html

2 Answered Questions

[SOLVED] Removing head tag from HTML

2 Answered Questions

[SOLVED] putting javascript after </html> tag

2 Answered Questions

[SOLVED] Put Scripts at the Bottom

  • 2011-02-09 17:27:06
  • Hacker
  • 2943 View
  • 5 Score
  • 2 Answer
  • Tags:   javascript

Sponsored Content