Link Javascript to HTML

Adding Javascript to HTML pages and all the tricky bits

Seann Hicks

Seann Hicks

Sunday, December 29, 2019

Link Javascript to HTML

Link Javascript to HTML 3D rendered

It is easy enough to link Javascript to HTML.  Javascript links can be added to the document head, or body, or both.  With HTML5, Javascript can also be loaded and executed before page load, during page load or after page load, and this is where it gets tricky.  In this post I cover Javascript linking, as well as loading and execution practices and where they are suitable.

Linking from HEAD

Linking Javascript to HTML from the HEAD of a document makes sense when you are loading a library of functions that the page uses. For example, you have wired up event handlers on elements that call functions defined in the linked library.  This is my default approach to link Javascript to HTML.  I like to keep Javascript out the document body and encapsulated in a page specific file that ties into page events to manipulate the DOM or provide functions that can be called by element events.

Here is an example of a script file called 'myscript.js' linked into a document 'head'.

<head>
<script src='myscript.js'/>
</head>

Linking from BODY

Loading Javascript in the body is when you have some script that needs to run when the page is loaded. I tend to stay away from this approach, however, it can be handy if you only have a few lines of code to run, or you need to manipulate an HTML document in a specific place.  The advantage of linking script in the body is when it occurs at the end of a document to optimize the load and execution of the script.

Script TYPE

The script 'type' attribute identifies the Internet media type (formerly known as the MIME type) of the script file. In HTML5, this attribute is no longer necessary. You may wish to include it to support pre-HTML5 browsers however. I tend to include it out of habit, but this is a a habit I am getting away from, mainly to keep HTML documents simpler.

Paths

File paths always cause me problems. So here is some quick guidance on how browsers use paths to locate script files.

Async

The async attribute allows Javascript to execute asynchronously while the page is parsing. If async is not specified, the page load waits until the javascript has been executed.  Waiting for large scripts can be a page performance problem.

<head>
<script src='myscript.js' async/>
</head>

Should async be added to every script?

The async attribute is specific to HTML5 and is a minimized version of the fully specified asyn='async'

Defer

Adding defer to a script element tells the browser to load the script but execute it after the page has been loaded. It used to be common practice to place script tags at the end of HTML documents to achieve this result.

<head>
<script src='myscript.js' defer/>
</head>

While scripts at the end of a document don't execute until the document DOM is loaded, that also aren't loaded either. The 'defer' attribute allows the browser to load the JS file, and defer the execution, instead of deferring the script load and the execution.

Async and Defer are only valid for external scripts. They are ignored if there is no 'src' attribute.  Async and Defer are only relevant to script tags specified in the document HEAD.  If you use both async and defer together, async will take precedence.  I believe specifying both is a mistake because you will get unpredictable results across browsers, depending on what functionality is supported, and your code is confusing as these attributes have different intentions. 

Dynamic Scripts

Javascript files can be added dynamically to a page (by Javascript).

var script = document.createElement('script');
script.src = 'myscript.js';
document.body.append(script);

By default, dynamic scripts are loaded asynchronously. This can be changed by setting the 'async' attribute on the script element to false.

Dynamically loading scripts at the bottom of an HTML document is the optimal approach for page load because the script is neither loaded nor executed until the page render is complete. This approach is also the most cross browser friendly as it does not rely on the 'asyn' or 'defer' attributes. Remember that javascript that is needed to render the page will need to load earlier. Move this code to a new file and link it in the document head with a 'defer' so that it can act on loaded DOM elements.

More Info

Here is some additional information on async and defer.

Some arguments for dynamic loading Javascript.

And, a post I wrote on 7 Free XML validation tools that can be used to validate your HTML documents - check it out.

Sign-up to receive the weekly post in your inbox. I don't share email addresses, unsubscribe at any time.

Email Address