In this tutorial, you will learn about the defer attribute and how it can be used within your web pages to improve page load times. When crafting a beautiful website, speed matters. One big factor that can impact page performance, is requests to scripts and stylesheets. How scripts are loaded can massively affect performance. There are several tips and tricks you can adopt to lessen this impact. For example, the position of where scripts are requested on a page is important. Things get more challenging if the page needs to load multiple Javascript files and the order in which those files is processed is important. If your website uses a module and you need all your scripts to have been pre-loaded before it is run, what do you do? If you want to learn how to solve this problem then read on!

The standard way to import a new Javascript script onto a page is like this:

When using a standard script import, the position of the tag within the page markup is important. When a browser parses a line like this, it will make a request to fetch the script. When the script successfully loads, the browser will continue on its merry way and attempt to parse the remaining parts of the page. If you add this script at the top of the page and it takes a long time to load, it will block the browser from loading the rest of the page. A large script or a slow request will block the whole page from loading... nightmare! This is why most script tags are added at the end of a page, to minimize this potential performance impact.

Defer

The defer attribute is a cheeky attribute that you can add to the script loading tag. defer tells the browser to act slightly differently when it tries to load that script. The defer attribute is applied onto a script tag like this:

Scripts marked using the defer attribute tell the browser to download the script asynchronously. When the browser downloads a script asynchronously, it will not block the rest of the page from loading. defer tells the browser to make a request to load the script and carry on parsing the page. Using defer, the script will only be parsed after it has been downloaded. The other great thing about defer is that all scripts will be executed in the order that you add them in the markup, even though they are being loaded asynchronously 💥

Async

There is an alternative attribute async that does a similar job as defer. Using the async attribute on script load is better than loading a script normally as it will also prevent render-blocking. The issue with async is that the order in which the scripts are run can not be guaranteed. When using the async attribute, requests to scripts are run when they are ready. This can cause a race condition and can mean your scripts are run in a different rider than you expected them to run. This can cause bugs and oddities when the page loads! For example, the browser might try to parse the main script before a reliant third-party vendor bundle is loaded, causing an error!

Ideal Set-up

You want to ensure that your CSS is loaded first. This means you add CSS first at the top of your page in the head. Applying defer to the script tags means that you can add your script loads at the top of the page. As script loading is one of the longer parts of the page load, adding it first with defer should lessen the total page load time. Using defer is an optimal way of declaring your scripts. A recommended order to call your CSS and Javascript files (with the correct attributes) is shown below:

The CSS will load straight away so the page looks nice. Next, using defer, a vendor bundle is requested, followed by the site's main Javascript file. The browser will continue to parse the HTML while downloading these scripts in the background. After the HTML has been parsed, if the script file is ready, the browser will then run the Javascript in the order you defined them in the mark-up. Adopting this technique should make your page load times quicker. If you are worried that your JavaScript file might run before the HTML is loaded, you can wrap your custom Javascript in an event handler like this:

The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets. All scripts decorated with the defer attribute will be loaded before this event is fired. If you wrap your main code in the domContentLoaded event and your site script is referenced last in the page's markup, you can guarantee that your Javascript will only run when everything has loaded. You can safely put your script references at the top of the page, maximizing performance. This is why using defer makes more sense when using the script in the head portion of the page! Happy Coding 🤘