Why Put Your JavaScript at the Bottom

When JavaSript was first created the only way to attach event processing to the web page was to embed the JavaScript event handlers into a web page was to embed them into the HTML itself. There was no simple way to reference parts of the HTML (other than forms) from JavaScript and so being able to keep the two separate was impossible.

As a result, whenever you wanted to attach the same scripts to multiple pages (and some sites like this one have thousands of pages) you had to put at least a part of the JavaScript into every page. If there were changes needed they'd have to be applied to every page. Simply adding a single parameter to a single event handler could take weeks to apply.

The introduction of the Document Object Model resolved this issue by providing ways to reference the HTML from a separate JavaScript. This meant that you could attach a single JavaScript to all the pages and make all of the event handling changes in one place rather than having to update each page. This made embedding the the event handlers in the HTML as dead as using tables for layout as both of these suffered from the same problem and were fixed by the introduction of the DOM and CSS respectively. Unfortunately while most people now realise that using HTML tables for layout is wrong there are many who still seem unaware that the same reasoning applies to JavaScript embedded in the HTML.

The introduction of event listeners and Immediately Invoked Function Expressions took this one step further by allowing the JavaScript to be made almost completely unobtrusive. No longer could separate JavaScripts interfere either with each other or with other parts of the web page. Two event listeners listening for the same event on the same element could now run independently and would only interfere with one another if what they were trying to do actually conflicted (such as attaching a scroll down script and a scroll up script to the same element and trying to run both at the same time).

There are so many benefits to not jumbling the JavaScript with the HTML that it is really amazing that there are still people writing their web pages that way. Presumably they have learnt Netscape JavaScript by copying other Netscape JavaScripts and have never realised that there have been several far superior versions of JavaScript released since then.

Once you reach the point of completely separating the JavaScript from the HTML there are two places in the HTML where you can place the script tag that attaches them together. Now the Document Object Model requires that the HTML you want to attach your JavaScript event listeners to must have already loaded in the web page before the listener can be attached. The script therefore needs to run after those HTML elements have loaded. The simplest place to put the script is therefore the bottom of the body of the page where it will be run immediately after all of the HTML has loaded.

Placing the script in the head of the page was common back in the days of embedding event handlers in the HTML as this ensured that the functions that those handlers called were already loaded by the time that the handler was added to the page. This avoided the problem of a handler trying to call a function that wasn't loaded yet. So for the same reason Netscape scripts needed to be added in the head, modern scripts need to be added to the bottom of the body.

There are other reasons for not attaching scripts in the head. As Netscape scripts could use a command called document.write() to actually generate HTML to be added to the page, any JavaScript had to be fully loaded and run in order that such statements if any could add their HTML before anything further in the HTML could be processed. Even where these obsolete commands are not used the browser doesn't know that until after the entire script has loaded and been run. So scripts attached in the head would prevent any of the body of the page loading until after the script had loaded and run.

There are a couple of very specific situations where this is actually a benefit. Prior to ways being introduced on the server to prevent your page displaying in someone else's frames and so look like it is a part of their site it used to be common to include a one line script in the head to reload the page outside of any frames if the script detected it was loading in a frame. A more modern reason for including a script in the head that takes advantage of the page not starting to load until after the script has run is where you test for specific JavaScript support and add classes to the HTML tag based on what JavaScript is supported so that the entire page can be styled based on what specific JavaScript commands the browser supports - the far more powerful replacement for the now obsolete noscript tag.

With these couple of exceptions you don't want to hold up displaying the web page while the JavaScript loads. Now the addition of the async and defer attributes to the script tag partly solves this in those browsers that support them by not stopping the page from continuing to load. The presence of either attribute tells the browser that the script doesn't contain any document.write() statements and so the page can continue to be rendered while the script is loading. The HTML itself can continue to be loaded into the browser but the JavaScript is still competing for bandwidth with the other files the page needs and so the page will still load slower with the script in the head than it will if you move the script to the bottom of the body.

In addition with the script in the head you need extra code to delay trying to add the event listeners until after the HTML finishes loading and not all browsers provide a way to test if the HTML is fully loaded without having to wait for all the other files to finish loading as well. Simply by moving the script to the bottom of the body you do away with the need for this extra code, speed up the rendering of the page, and get the script to run sooner than it otherwise might.

Google calls any script a blocking script if it is attached in the page at a point where it would slow the rendering of the part of the HTML above the fold. Such pages receive a penalty for this because they are slower loading than pages that don't contain blocking scripts. So for SEO purposes there is also a benefit to moving the script to the bottom of the body.

It is now over ten years since Netscape died and embedding JavaScript in the HTML or placing scripts (other than ones that specifically need to run before the page starts to render) in the head of the page was necessary. We ought to be able to assume by now that ALL JavaScript that doesn't need to run before the page renders will be in a separate file attached to the bottom of the body.

Attaching your scripts anywhere other than at the bottom of the body is a clear indication that you are at best a JavaScript beginner and need to forget about copying antiquated scripts from elsewhere on the web and actually learn modern JavaScript properly. There has also been sufficient time since attaching scripts at the bottom became best practice that all JavaScript classes should be teaching that. If you happen to take a JavaScript class that doesn't teach that scripts go at the bottom of the page then ask your teacher why they are still teaching an antiquate way of coding that has been obsolete for over ten years. You may still need to pass their history subject as a part of whatever course you are taking but you need to keep reminding yourself that it is a history class and not a programming class and that if you want to learn to write JavaScript you will need to forget what you learnt in history class and start over.


This article written by Stephen Chapman, Felgall Pty Ltd.

go to top

FaceBook Follow
Twitter Follow