DEV Community

Cover image for Load JavaScript optimally by utilizing defer.
Pramit Marattha
Pramit Marattha

Posted on

Load JavaScript optimally by utilizing defer.

This is by far the most important and awesome feature, and it's how you should load and import your JavaScript file from now on, so let's get started with our teeny-tiny demonstration.

On modern websites, scripts tends to be heavier than HTML: they take longer to download and process. Whenever the browser loads HTML and encounters a script tag, it is unable to continue generating the DOM(Document Object Model) that's because the script must be loaded instantaneously.. External scripts are also treated similarly: the browser must first wait for the script to download, then run the downloaded script before continuing parsing the rest of the HTML.

So, initially, let's start by creating two files, one called index.html and the other called script.js, and inside the index.html file, add some simple boilerplate code by using the HTML snippets extension or you can simply copy the code mentioned below.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Script: defer</title>
</head>
<body>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Now, inside our body, we'll just make a simple button with some text on it, and then inside our head, we'll add a script tag and import our script.js file which we just created.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Script: defer</title>
    <script src="./scripts.js"></script>
</head>

<body>
    <button>Hello There!</button>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

Once you've done that, open that index file in your browser with the live server, and you'll notice that there's a very basic looking button.

Button Demo

Let's add some simple script to manipulate our button, so copy and paste the following JavaScript code into your script.js file.

// scripts.js
const body = document.querySelector('body');
const btn = document.querySelector('button');

btn.style.display = 'block';
btn.style.position = 'absolute';
btn.style.left = '50%';
btn.style.top = '50%';
btn.style.transform = 'translate(-50%, -50%)';
btn.style.width = '200px';
btn.style.height = '100px';
btn.style.fontSize = '2rem';
btn.style.fontFamily = 'sans-serif';
btn.style.borderRadius = '10%';
btn.style.backgroundColor = '#8661d1';
btn.style.color = '#fff';
btn.style.border = 'none';
btn.style.outline = 'none';
btn.style.cursor = 'pointer';
btn.style.boxShadow = '0 0 10px #000';
btn.style.transition = 'all 0.5s ease-in-out';
btn.addEventListener('mouseenter', () => {
    btn.style.backgroundColor = '#FD5252';
});
btn.addEventListener('mouseleave', () => {
    btn.style.backgroundColor = '#8661d1';
});
btn.addEventListener('click', () => {
    body.style.backgroundColor = '#FD5252';

    setTimeout(() => {
        body.style.backgroundColor = '#fff';
    }, 1000);
});
btn.addEventListener('transitionend', () => {
    btn.style.backgroundColor = '#8661d1';
});
Enter fullscreen mode Exit fullscreen mode

So, in this script, we first selected the body, then the button, then we apply a range of styles to that button, and then we proceed to add some event listeners, and finally we stated what that button should do in a specific event, and that's it, our button has been totally controlled using the absolute power of JavaScript.

Button

If you refresh your browser, you will notice no any changes on the site, it's because our script is up in the head, which is normally bad because it means that your JavaScript is loading way before the body itself. To fix this, simply add a defer inside the script tag.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Script: defer</title>
    <script src="./scripts.js" defer></script>
</head>

<body>
    <button>Hello There!</button>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

We simply deferred our script in the above code, which means that our script guarantees that our overall body loads before running any of our JavaScript. So, once you've done that, your index.html file should look like this.

Now go to your browser and reload it, and you should see something similar to this.

Button Demo GIF

If we remove this defer, you'll find that our button doesn't work; instead, we get an error that says cannot read property style of null.

Error

We'll get this error because when we get to our script tag, it stops parsing the rest of our html, but proceeds to the script, and only after that it continues parsing, which means the button never got added to our page. However, if we put defer in the script tag, it downloads all the JavaScript but then continues rendering everything, so it renders our button first, then begins rendering the complete page once the script has been downloaded.

People frequently put the script at the bottom, which works just fine, but the problem with this is that the download for the script doesn't start until the browser renders the entire page, which means it could slow down your website's loading speed and might make the site disorganized and unappealing.

Hence, by simply placing your JavaScript in the head and ensuring that defer is set, you will never have to wait for DOM events to load, nor will you have to deal with the inconvenient nature of placing your JavaScript towards the end of your body, which is tedious and awful.

So, from now on, keep your script at the head. All you have to do is just defer it, and it will do the same thing as putting your script towards the bottom, but it will help your webpage or website load even more faster.

Discussion (0)