Inserting JavaScript into an HTML page

The primary way to include a script in a webpage is through the <script> tag. There are two methods: direct embedding and external file inclusion. For direct embedding, you place the JavaScript code directly within the HTML file using <script> tags. This approach is suitable for small code snippets or when immediate script execution is needed. Alternatively, you can include an external JavaScript file by referencing it using the <script> tag's src attribute. This method promotes code modularity, reusability, and easier maintenance. It improves the HTML file's structure and readability while allowing code reuse across multiple web pages.



Direct embedding

To include JavaScript code directly in your HTML file, you can place the code inside the <script> element like this:

<script>
  function greet() {
    console.log("Hello world");
  }
</script>

The JavaScript code written inside a <script> element is read and executed from the top to the bottom. In this example, a function is defined and stored in the JavaScript environment. The remaining content of the webpage is not loaded or displayed until all the code inside the <script> element has been evaluated. It ensures that the function is available and ready to be used before the webpage continues rendering or processing other elements.



JavaScript from an external file

To include JavaScript code from an external file, you need to use the src attribute. The src attribute requires a URL that points to a file containing the JavaScript code. Here's an example:

<script src="path/to/file.js"></script>

In this example, we are loading an external file called "file.js" into the webpage. The "file.js" file only needs to contain the JavaScript code that would typically be placed between the <script> and </script> tags. Similar to inline JavaScript code, the page processing pauses while the external file is being interpreted. Additionally, there is some time taken to download the external file from the server before it can be executed.

It's important to remember that when using the src attribute in a <script> element, additional JavaScript code should not be placed between the <script> and </script> tags. If both are included, the browser will download and execute the script file specified in the src attribute, while ignoring any inline code written between the <script> and </script> tags.

One of the remarkable and sometimes debated features of the <script> element is its capability to include JavaScript files from external domains. By using the src attribute of the <script> element, you can specify a complete URL that points to a JavaScript file located outside the domain of the HTML page. Here's an example:

<script src="http://somewhere.com/file.js"></script>

When you include JavaScript code from an external domain, it will be loaded and interpreted as if it were a part of the webpage itself. This feature allows you to fetch JavaScript from different domains if required. However, it's important to exercise caution when referencing JavaScript files hosted on a server that you don't have control over. There's a risk that a malicious programmer could replace the file with malicious code. To defend against this potential risk, the <script> tag provides the integrity attribute. This attribute allows you to specify a cryptographic hash of the external file's content. The browser can then verify the integrity of the file by comparing the provided hash with the calculated hash of the downloaded file. By using the integrity attribute, you can add an extra layer of protection and ensure that the included JavaScript file hasn't been tampered with.

The <script> elements on a webpage are processed sequentially, following the order in which they appear. The JavaScript code inside the first <script> element must be fully processed before the second <script> element is executed. Similarly, the second <script> element must complete its processing before the third one, and so on.

Tag Placement

In the past, it was common practice to put all <script> elements inside the <head> section of a webpage. This means that the JavaScript code was included before the actual content of the page. Here's an example:

<!DOCTYPE html>
<html>
<head>
    <title>Example HTML Page</title>
    <script src="file1.js"></script>
    <script src="file2.js"></script>
</head>
<body>
    <!-- Content goes here -->
</body>
</html>

However, when you include all JavaScript files within the <head> section of a webpage, it means that the browser needs to download, analyze, and interpret all of that JavaScript code before it can start rendering the page (rendering starts when the browser encounters the opening <body> tag). This can lead to a significant delay in rendering the page, especially if there are many JavaScript files or if they are large in size. During this delay, the browser will appear blank, without any content displayed. Due to this reason, modern web applications usually place all JavaScript references within the <body> element, after the page content. Here's an example to illustrate this:

<!DOCTYPE html>
<html>
<head>
    <title>Example HTML Page</title>
</head>
<body>
    <!-- Content goes here -->
    <script src="file1.js"></script>
    <script src="file2.js"></script>
</body>
</html>

Using this approach, the browser can fully render the page before processing the JavaScript code and the amount of time spent on a blank browser window is reduced.



'defer' attribute

The "defer" attribute serves to indicate that a script will not modify the structure of the page while it is executing. By using the "defer" attribute on a <script> element, we inform the browser to start downloading the script immediately, but postpone its execution until the entire page has been parsed. This ensures safe and efficient handling of scripts without interfering with the page rendering process.

<!DOCTYPE html>
<html>
<head>
    <title>Example HTML Page</title>
    <script defer src="file1.js"></script>
    <script defer src="file2.js"></script>
</head>
<body>
    <!-- Content goes here -->
</body>
</html>

In this example, even though the <script> elements are placed in the document <head>, they won't be executed until the browser reaches the closing </html> tag.

According to the HTML5 specification, scripts are executed in the order they appear. Therefore, the first deferred script executes before the second one, and both are executed before the DOMContentLoaded event. However, in practice, deferred scripts may not always execute in order or before the DOMContentLoaded event. It is advisable to include just one deferred script whenever possible to avoid potential inconsistencies.



'async' attribute

The "async" attribute is used to enable asynchronous loading and execution of scripts. Scripts with the "async" attribute are not guaranteed to execute in the order they are specified, as they start executing as soon as they are downloaded, regardless of the order.

<!DOCTYPE html>
<html>
<head>
    <title>Example HTML Page</title>
    <script async src="file1.js"></script>
    <script async src="file2.js"></script>
</head>
<body>
    <!-- Content goes here -->
</body>
</html>

In the code, the second script file may execute before the first one, so it's crucial that there are no dependencies between them. By using the "async" attribute, we indicate that the page doesn't have to wait for the script to be downloaded and executed before continuing to load. It also doesn't have to wait for another script to load and execute. Therefore, it's recommended that asynchronous scripts do not make changes to the page's structure while loading.

Asynchronous scripts are guaranteed to execute before the page's load event, but their execution may occur before or after the DOMContentLoaded event.



Dynamic Script Loading

You are not limited to using static <script> tags to load resources. Because JavaScript is able to use the DOM API, you can dynamically add script elements to the page, which in turn will load the specified resources. This can be achieved by programmatically creating script elements and attaching them to the DOM structure:

let scriptElement = document.createElement('script');
scriptElement.src = 'filename.js';

// If needed, you can also add other attributes to the <script> element
// scriptElement.async = true; // for asynchronous loading
// scriptElement.defer = true; // for deferred loading

document.head.appendChild(scriptElement); // Add to the DOM

Note that the request to fetch the script file will be initiated and sent to the server once the scriptElement is attached to the DOM. This is because the browser begins fetching external resources, such as scripts, stylesheets, or images, only when they are added to the DOM.

By default, scripts that are created in this fashion are async.

To inform browsers of the existence of these dynamically requested files, you can explicitly declare them in the document head:

<link rel="subresource" href="filename.js">