Loading JavaScript Code For Performance
Tags: javascript, beginners, script, performance
Published: 2019-12-01 17:13:56

For the browser to run JavaScript, it needs to download, parse, and run the code. It takes time for each of the steps, and the more script files you have, the longer it takes to be executed. If the scripts are loaded at the wrong time, it will block other content.

## How Scripts Load

When the browser sees a script tag in the HTML document, it stops other actions until it resolves that script. Take the following example:

```html
<head>
  <script src="myscript.js"></script>
</head>

<body>
  <h1>Hello!</h1>
</body>
```
The script with a source path is specified in the `<head>` element. The browser will ask a server for `myscript.js` file, download, parse, and execute it. But while it is happening, the rendering (browsers process for showing visual content) will be blocked.

## Loading Script In The Body

A good start for loading the script would be placing it at the bottom of the body element. Or if you have a tiny chunk of code, it can be written directly in the script element in HTML document, that way saving some request time:

```html
<head>
  <script type="text/javascript">
    document.querySelector("h1").innerHTML = "Hello JavaScript!";
  </script>
</head>

<body>
  <h1>Hello!</h1>

  <script src="myscript.js"></script>
</body>
```
But even placing scripts at the bottom of the body element, browser will load them soon anyways. This can be optimized even more.

## Script Attributes `async` And `defer`
 
Script tag has `async` and `defer` attributes that help script to execute more efficiently.
The `async` attribute tells the browser that a script should be, if possible, downloaded asynchronously and executed as soon as finishes the download. It doesn't block the rendering process. Use it only if the `src` attribute is present:

```html
<script src="myscript.js" async></script>
```

The `defer` attribute does even more. It downloads the script asynchronously, and execute the code after the page has finished parsing. This also prevents render-blocking. Using `defer`, a script tag should have a source attribute as well:

```html
<script src="myscript.js" defer></script>
```
Both tags should not be used at the same time.

## `load` Event

The last method for loading the script as late as possible in the page rendering is using the `load` event. After the page finishes downloading resources (stylesheets, images, scripts), the `load` event is fired.
To make use of this event, we need to create a `window` event listener and bind the `load` event to it. In the callback, create a script tag, add source attribute, and append to the body element. This way we guarantee to load and execute the script when the visuals appear on the page.

```js
window.addEventListener('load', function() {
  const script = document.createElement('script');
  script.src = 'myscript.js';
  body.document.appendChild(script);
});
```

## Conclusion

Loading scripts in the body and using `async` or `defer` attribute is a great start to improve page performance.
And if your goal is to get out the most of the performance and user experience, then loading scripts after the `load` event is the way.